什么是多态?
同类型的对象,执行同一个行为,会表现出不同的行为特征
多态的常见形式
父类类型 对象名称=new 子类构造器
接口 对象名称=new 实现类构造器
多态成员访问特点
方法调用:编译看左边,运行看右边
变量调用:编译看左边,运行看右边(多态侧重行为多态)
多态的前提
有继承/实现关系;有父类引用指向子类对象,有方法重写
多态的优势:
优势:在多态形式下,右边对象可以实现解耦合,便于扩展和维护
定义方法的时候,使用父类型作为参数,该方法就可以接收这父类的一切子类对象,体现出多态的扩展性与便利
多态下会产生的一个问题:
多态下不能使用子类的独有功能
自动类型转换(从子到父):子类对象赋值给父类类型的变量指向
强制类型转换(从父到子):必须进行强制类型转换:子类 对象变量=(子类)父类类型的变量
作用:可以解决多态下的劣势,可以实现调用子类独有的功能
注意:如果转型后的类型和对象真实类型不是同意中类型,那么在转换的时候就会出现ClassCastException
java建议强制转换前使用instanceof判断当前对象的真实类型,再进行强制转换
变量名 instanceof 真实类型
判断关键字左边的变量指向的对象的真实类型,是否是右边的类型或者是其子类类型,是则返回true,反之
内部类:
内部类就是定义在一个类里面的类,里面的类可以理解成(寄生),外部类可以理解成(宿主)
内部类的使用场景、作用
当一个食物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又职位外部事物提供服务,那么整个内部的完整结构可以选择使用内部类来设计
内部类通常可以方便访问外部类的成员,包括私有的成员
内部类提供了更好的封装性,内部类本身就可以用private protected等修饰,封装性可以做更多控制
静态内部类
什么是静态内部类?有static修饰,属于外部类本身
他的特点和使用与普通类是完全一样的,类有的成分它都有,只是位置在别人里面而已
public class Outer{
//静态成员内部类
public static class Inner{
}
}
静态内部类创建对象的格式:
格式:外部类名.内部类名 对象名=new 外部类名.内部类构造器;
范例:Outer.Inner in=new Outer.Inner();
成员内部类
匿名内部类:
本质上是一个没有名字的局部内部类,定义在方法中,代码块中
作用:方便创建子类对象,最终目的为了简化代码编写
格式:
Employee a=new Employee(){
public void work(){
}
}
a.work;
特点总结:
匿名内部类是一个没有名字的内部类
匿名内部类写出来就会产生一个匿名内部类对象
匿名内部类的对象类型相当于是当前new的那个类型的子类类型
匿名内部类的作用?
方便创建子类对象,最终目标为了简化代码编写
package d6_innerclass_anonymous;
public class Test2 {
public static void main(String[] args) {
Swimming s=new Swimming() {
@Override
public void swim() {
System.out.println("学生快乐的自由泳");
}
};
go(s);
}
//学生 老师 运动元可以一起参加比赛
public static void go(Swimming s){
System.out.println("开始");
s.swim();
System.out.println("结束");
}
}
class Student implements Swimming{
@Override
public void swim() {
System.out.println("学生快乐的自由泳");
}
}
interface Swimming{
void swim();
};
匿名内部类在开发中的真实使用场景:
给按钮绑定点击事件
Object类的作用:
一个类要么默认继承了Object类,要么间接继承了Object类,Object类是java中的祖宗类
Object类的方法是一切子类都可以直接使用的,所以我们要学习Object类的方法
Object类的常用方法:
public String toString() 默认是返回当前对象在堆内存中的地址信息:类的权限名@内存地址
public Boolean equals(object o):默认是比较当前对象与另一个对象的地址是否相同,相同则返回true,不同返回false
问题引出:
开发中直接输出对象,默认输出对象的地址其实都是毫无意义的
开发中输出对象变量,更多的时候是希望看到对象的内容数据而不是对象的地址信息
toString存在的意义
父类toString()方法存在的意义就是为了被子类重写,以便返回对象的内容信息,而不是地址信息!
可以快捷键生成
Object的toString方法的作用是什么?
默认是打印当前对象的地址
让子类重写,以便返回子类对象的内容
Object的equlas方法:
public Boolean equals(Object o) 默认是比较当前对象与另一个对象的地址是否相同,相同返回true,不同返回false
直接比较两个对象的地址是否相同完全可以用==替代equals
想要比较内容就需要重写一个equals方法
@Override
public boolean equals(Object o) {
//判断是否是同一个对象比较,如果是返回true
if (this == o)
return true;
if (o == null || getClass() != o.getClass()) return false;
Studet studet = (Studet) o;
return sex == studet.sex && age == studet.age && Objects.equals(name, studet.name);
}
object的equals方法的作用是什么?
默认是与另一个对象比较地址是否一样
让子类重写,以便比较2个子类对象的内容是否相同
Objects
Objects类与Object还是继承关系,Objects类才是JDK1.7开始之后才有的
官方在进行字符串比较时,没有对象自己的equals方法,而是选择了Objects的equals方法来比较两个对象
Objects的equals方法比较的结果是一样的,但是更安全,不会出现空指针异常
Objects的常见方法
public static boolean equlas(Object a,Object b) 比较两个对象的,底层会先进行非空判断,从而可以避免空指针异常。再进行equals比较
public static boolean isNull(Object obj) 判断变量是否为null,为null返回true,反之false
源码分析:
public static boolean equlas(Object a,Object b){
return (a==b)||(a!=null&&a.equlas(b));
}
Objects.isNull(对象名);
对象进行内容比较的时候建议使用什么?为什么?
建议使用Objects提供的equals方法
比较的结果是一样的,但是更安全
StringBuilder概述:
StringBuilder是一个可变的字符串类,我们可以把它看成是一个对象容器
作用:提高字符串的操作效率,如拼接,修改等
StringBuilder构造器
public StringBuilder() 创建一个空白的字符串对象,不包含任何内容
public StringBuilder(String str) 创建一个指定字符串内容的可变字符串对象
String类拼接字符串原理图

解析:创建s1时,字符串常量池中添加"a"
创建s2时,字符串常量池中添加"b",并且在堆内存中创建一个对象,new StringBuilder(),在 通过toString添加到String中
StringBuilder内存图

为什么拼接、反转字符串建议使用StringBuilder?
String:内容是不可变的,拼接字符串性能
StringBuilder:内容是可变的,拼接字符串性能好,代码优雅
定义字符串使用String
拼接、修改等操作字符串使用StringBuilder
package d11_api_stringbuilder;
public class StringBuilderDemo2 {
public static void main(String[] args) {
int[] arr1=null;
System.out.println(arr1);
int[] arr2={10,28,39,76};
System.out.println(toString(arr2));
}
/*1.定义方法接受任意整形数组,返回数组内容格式*/
public static String toString(int[] arr){
if(arr!=null){
//2.开始拼接内容
StringBuilder sb = new StringBuilder("[");
for (int i = 0; i < arr.length; i++) {
sb.append(arr[i]).append(i==arr.length-1?"":",");
}
sb.append("]");
return sb.toString();
}else{
return null;
}
}
}
Math类
包含执行基本数字运算的方法,Math类没有提供公开的构造器
如何使用类中的成员呢?看类的成员是否都是静态的,如果是,通过类名就可以直接调用

package d11_api_stringbuilder;
public class StringBuilderDemo3 {
public static void main(String[] args) {
//1.取绝对值:返回正数
System.out.println(Math.abs(-10.7));//10
//2.向上取整:5
System.out.println(Math.ceil(4.000007));//5
//3.向下取整:4
System.out.println(Math.floor(4.99999));//4
//4.求指数数次方
System.out.println(Math.pow(2.3,4.6));
//5.四舍五入
System.out.println(Math.round(4.499999));
System.out.println(Math.round(4.500001));
//四舍五入
System.out.println(Math.random());
}
}
System类概述:
System的功能是通用的,都是直接用类名调用即可,所以System不能被实例化
Syste,类的常用方法
public static void exit(int status) 终止当前运行的Java虚拟机,非零表示异常终止
public static long currentTimeMillis() 返回当前系统的时间毫秒值形式
public static void arraycopy(数据源数组,起始索引,目的地数组,起始索引,拷贝个数) 数组拷贝
import java.util.Arrays;
public class d12_system {
public static void main(String[] args) {
System.out.println("程序开始");
//System.exit(0);
//1.计算机认为时间有起源:
long time = System.currentTimeMillis();
System.out.println(time);
long startTime = System.currentTimeMillis();
//进行时间的计算。性能分割
for (int i = 0; i < 10000; i++) {
System.out.println("输出..."+i);
}
long endTime = System.currentTimeMillis();
System.out.println((endTime-startTime)/1000.0+"s");
/*arraycopy(Object src,int srcpas
* ,Object dest,int desPas,int length)
* */
int[] arr1={10,20,30,40,50,60};
int[] arr2=new int[arr1.length];
System.arraycopy(arr1,3,arr2,2,3);
System.out.println(Arrays.toString(arr2));
System.out.println("程序结束...");
}
}
BigDecimal作用
用于解决浮点型运算精度失真的问题
创建对象BigDecimal封装浮点型数据(最好的方式是调用方法)
public static BigDecimal valueOf(double val):包装浮点数成为BigDecimal对象

BigDecimal的作用是什么?
解决浮点型运算精度失真问题
BigDecimal的对象如何获取?
BigDecimal b1=BigDecimal.valueOf(0.1);
BigDecimal必须解决精度运算,如果进行10/3的运算,会报错,需要做取整 操作










