面向对象第三天
- 多态
- 面向对象的三大特征之一:封装、继承、多态
- 含义? 指的是对象有多种形态
- 人类型的对象:学生对象
- 人类型的对象:老师对象
- 人类型的对象:丈夫对象
- 语法形式:
- 父类类型 变量名称 = new 子类构造器;
- Animal a = new Cat();
-
- 接口 变量名称 = new 实现类构造器;
- 多态的调用方式
- 对于方法的调用:编译看左边,运行看右边
-
- Animal a = new Cat();
- a.run();
-
- 对于变量的调用
-
- 编译看左边,运行也看左边(注意)
- 多态的使用前提
- 1、必须继承、实现
- 2、父类类型的变量指向子类类型的对象
- 多态的使用前提
- Animal a = new Cat();
-
- 3、存在方法重写
-
- Animal a = new Cat();
- a.run();
- 多态的优势
- a、多态可以实现解耦合
- 多态的优势
- Animal a = new Dog();
- a.run();
-
- b、多态下,父类类型作为方法的入参,可以接收一切子类对象,这样更利于方法的扩展和便利性。
- 注意存在的问题:
-
- 多态下不能直接访问子类独有功能
• Animal a = new Dog();
• a.lookDoor();
-
- 多态下类型转换问题
- 自动类型转换
- 多态下类型转换问题
- 从字到父
- Animal a = new Dog();
-
- 强制类型转换
-
- 从父类到子类
• Animal a = new Dog();
• 必须强制类型转换,否则报错的
• Dog d = (Dog)a;
- 注意:
• Java规定,有继承/实现关系的类就可以强制转换,编译阶段不会报错。但是运行时可能出现类型转换异常
• Animal a = new Cat();
• Dog d = (Dog)a;
• 编译不出错。运行时出现类型转换异常。
- Java建议在进行强制转换之前先通过instanceof判断真实数据类型,再强转
• Animal a = new Cat();
• a instanceof Cat
• Cat c = (Cat)a;
- 强制类型转换解决了什么问题??? 可以调用子类的独有功能了
- 内部类
- 是什么??
- 类的5大金刚(成员变量、成员方法、构造器、代码块、内部类)
- 类中的类
- 内部类有几种
- 1、静态内部类
- 是什么??
- 是什么?有static修饰,属于外部类本身。
• 特点:只是位置在类里面。类有的成分它都有。
- 创建对象:
• 外部类.内部类名 对象名 = new 外部类名.内部类构造器;
- 拓展
• 1、静态内部类可以直接访问外部类的静态成员吗? 可以的
• 2、静态内部类中是否可以直接访问外部类的实例成员? 不可以的
-
-
- 2、成员内部类(实例内部类)
-
- 是什么?
• 无static修饰,属于外部类的对象的。
- 特点:JDK 17中类有的成分,它都有。
- 创建对象 : 外部类.内部类 对象名 = new 外部类构造器.new 内部类构造器;
- 面试题
•
-
-
- 3、局部内部类
-
- 定义在方法中,代码块中,构造器中,执行代码处的类。鸡肋语法!
-
- 4、匿名内部类(重点)
-
- 重点:
• 方便构建子类对象,最终目的:简化代码
- 格式:
• new 类名|接口|抽象类(){ 方法重写 }
- 特点:
• 匿名内部类是一个没有名字的局部内部类,本身也是一个所谓的子类对象。
• 匿名内部类这个对象的类型,相当于是当前new的这个类型的子类类型
- 常用API
- API概述
- 应用程序编程接口。
- API概述
- Java写好的程序,程序员可以直接调用。
- Object类:toString方法
- Object是祖宗类,它里面的方法,是一切子类对象都可以使用。
- 1、public String toString()
- Object类:toString方法
- 默认是返回当前对象的地址信息。
-
- 2、Student s = new Student("张三",'女', 23);
-
- System.out.println(s.toString());
• 返回对象地址
- System.out.println(s);
• 直接输出对象名,默认是调用toString方法的
-
-
- toString存在的意思:
-
- 默认返回对象的地址其实是没有意义的
- 真实存在的意义是被子类重写,以便返回子类对象的内容。
- Object类:equals方法
- 1、public boolean equals(Object o )
- Object类:equals方法
- 默认是比较2个对象的地址是否一样,返回true 或者false
-
- equals存在的意义
-
- 默认比较对象的地址其实是没有意义的,因为== 号可以更简单的完成
- 存在的的真实意义是被子类重写,以便比较对象的内容。
- Objects
- Objects是一个工具类,提供了更安全的方式比较2个对象。
- Student s = null;
- Objects
- s.equals(s2); 空指针异常
- Objects.equals(s, s2); 返回false
-
-
- StringBuilder
- StringBuilder称为可变字符串容器,操作字符串的性能由于String类。
- StringBuilder
-
-
- StringBuilder拼接操作字符串的手段:性能好
- String才是结果数据的类型:目的
- Math
- Math相当于是一个工具类,提供的方法全部是完成数学操作的静态方法,直接用类名调用即可。
- // 目标:看看Math类的方法就行了。
// 1、取绝对值(拿到的结果一定是正数)
System.out.println(Math.abs(-12));
System.out.println(Math.abs(-12.2));
System.out.println(Math.abs(1443));
// 2、向上取整
System.out.println(Math.ceil(3.000001)); // 4.0
System.out.println(Math.ceil(4.0)); // 4.0
// 3、向下取整
System.out.println(Math.floor(3.9999999)); // 3.0
System.out.println(Math.floor(3.0)); // 3.0
// 4、四舍五入
System.out.println(Math.round(3.45555)); // 3
System.out.println(Math.round(3.500001)); // 4
// 5、取较大值
System.out.println(Math.max(10, 20));
// 6、取次方
System.out.println(Math.pow(2, 4)); // 16.0
System.out.println(Math.pow(3, 2)); // 9.0
// 7、取随机数(用的少)
System.out.println(Math.random()); // [0.0 , 1.0) (包前不包后)
- System
- System代表系统,也是一个工具类的形式,里面的方法都是与系统操作相关的静态方法。
- // 目标:了解下System类的几个方法。
// 1、终止虚拟机(干掉全部Java程序的执行)
System.out.println("程序开始。。。");
// System.exit(0); // 0代表是人为认为的正常终止的 (慎用)
// 2、获取当前系统的时间信息的。(时间毫秒值:从1970-1-1 0:0:0开始走到此刻的总的毫秒值。1s = 1000ms)
long time = System.currentTimeMillis();
System.out.println(time);
// 通常用来统计程序执行的性能问题。
for (int i = 0; i < 2000; i++) {
System.out.println("输出:" + i);
}
long time2 = System.currentTimeMillis();
System.out.println("耗时:" + (time2 - time) / 1000.0 + "s");
// 3、获取当前系统的各种信息。
System.out.println(System.getProperties());
// 4、提供了一个数组元素拷贝的方法。
int[] arr1 = {10, 20, 30, 40, 50, 60, 70};
int[] arr2 = new int[6]; // [0, 0, 0, 0, 0, 0] == > [0, 0, 40, 50, 60, 0]
/**
arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
参数一:原数组
参数二:拷贝元素的起始位置
参数三:目标数组
参数四:目标数组的粘贴起始位置
参数五:拷贝几个元素
*/
System.arraycopy(arr1,3,arr2,2, 3);
System.out.println(ArrayUtil.toString2(arr2));
System.out.println("程序结束。。。。");
- BigDecimal
- 代表大数据类型,封装double类型的数据进行运算的,为了解决计算精度问题
- 目前:浮点型 double运算是不精准。
-
- double a1 = 0.1
- double b1 = 0.2;
- double c1 = a1 + b1;
• 0.3000000000000001
- BigDecimal a = BigDecimal.valueOf(a1);
- BigDecimal b = BigDecimal.valueOf(b1);
- BigDecimal c = a.add(b);
- BigDecimal
• 解决精度问题的手段
- double
• public double doubleValue(); 把BigDecimal转化成double类型的数据
- BigDecimal a = BigDecimal.valueOf(0.1);
- BigDecimal b = BigDecimal.valueOf(0.3);
- BigDecimal c = a.divide(b);
• 报错的。结果不是精确的,一定报错
- BigDecimal c = a.divide(b,2,BigDecimal.ROUND_HALF_UP);
•