Java初学笔记8
1.多态
(1)能提高复用性
(2)重写与重载体现多态性
2.对象的多态
前提:两个对象(类)存在继承关系
(1)一个对象的编译类型与运行类型可以不一致
eg. A为B的父类 A a = new B ( ) ; 其中编译类型为A ,运行类型为B
(2)编译类型在定义对象时候就确定了,不会变
(3)运行类型是可以改变的
(4)= 左边为编译类型 = 右边为运行类型
3.向上转型
父类
class Fruit{
public void show() {
System.out.println("this is a fruit");
}
}
子类
class Apple extends Fruit{
@Override
public void show() {
System.out.println("this is a apple");
}
public void test() {
System.out.println("i am a apple");
}
}
调用方法
Fruit fruit = new Apple(); //this is a apple
fruit.show(); //报错
(1)父类的引用指向子类的对象
(2)在权限范围内,可以调用父类所有成员
(3)不能调用子类的特有成员
(4)运行时看运行类型,遵循就近原则
4.向下转型
Fruit fruit = new Apple();
Apple apple = (Apple) fruit; //向下转型
子类
class Orange extends Fruit{
@Override
public void show() {
System.out.println("this is a Orange");
}
public void test() {
System.out.println("i am a Orange");
}
}
Fruit fruit = new Apple();
Orange orange = (Orange) fruit; //编译成功,运行报错
(1)将父类引用强制转成子类引用
(2)只能强转父类引用,不能强转父类对象
(3)只能强转父类引用的前提:父类一开始就指向某一个子类对象
(4)只能强转父类引用的结果:转型后可以调用子类的所有成员
4.5 转型的好处
可以减少编程代码。
假设在主类中定义了一个run()方法,该方法传入一个Fruit参数,并调用了Fruit对象的show()方法,代码如下:
public static void run(Fruit fruit) {
fruit.show();
}
在main()方法中的代码如下:
public static void main(String[] args) {
run(new Fruit());
run(new Apple());
run(new Orange());
}
上述代码中,调用run()方法时的参数不仅是Fruit对象,也可以是Apple对象和Orange对象,当传入的是Apple对象和Orange对象时,就会向上转型成Fruit对象,但是调用的show()方法还是Apple对象和Orange对象的show()方法。
5.属性无多态之说
(1)属性的值直接看编译类型
(2)a instanceof b 判断a的运行类型是否为b的运行类型,或者判断a的运行类型是否为b的运行类型的子类型
6.动态绑定机制
(1)当调用对象方法时,该方法会和该对象的内存地址(运行类型)绑定
(2)调用对象属性时,没有动态绑定机制,哪里声明属性,哪里就调用属性
7.多态数组
(1)数组的定义类型为父类类型,而里面保存的实际元素类型为子类类型。
eg. A为B,C类的父类,A[ ] a = new A[ ] ;
a [0] = new A(xxx) ;a[1] = new B(xxx) ;a[2] = new C(xxx) ;
(2)多态数组常与:类型判断instanceof,向下转型相结合
8.多态参数
方法定义时,允许形参为父类类型,实参为子类类型。
多态的练习题
9.object类详解之equals方法
(1)==
可判断基本数据类型(判断值),引用数据类型(判断地址值)。
(2)equals
若在object类中,只能判断引用类型,即地址值是否一样;
若在子类中重写。如String类,Integer类,用于判断内部值是否一样。
10.object类详解之hashcode方法
(1)提高哈希表性能
(2)若引用指向同一对象,则哈希值一样;反之不一样。
(3)哈希值根据地址值而来,但是不能将哈希值等同于地址值。
(4)在集合中可以重写
11.object类详解之toString方法
(1)在object类中:
返回:包名 + 表名 + @ + 十六进制的哈希值
(2)在子类中:
重写该方法,是为了打印对象属性信息。
有默认形式,快捷键 alt + insert -> toString()
(3)输出对象时,toString默认被调用
即:a为A类的对象 ,以下两种情况等价
System.out.println(a);
System.out.println(a.toString);
12.object类详解之finalize方法
(1)在object类中:
当某个对象不存在引用时,由对象的垃圾回收器调用该方法把对象在堆中的空间释放。
(2)在子类中:
重写后,可以做一些资源释放操作,例如:数据库连接,打开文件。
有默认形式,快捷键 alt + insert -> finalize()
(3)垃圾回收机制由系统调用,有自己的GC算法来决定触发的阶段;人为可以主动触发回收机制,用System.gc( ) ;
object类的练习题
equals方法的重写
部分图片来自B站韩顺平老师