编程日记:Java学习之路(十)
多态
一、面向对象——多态
面向对象的三大特征:
封装——继承——多态
多态的分类:多态=编译时多态(重载)+运行时多态(引用多态)
什么是多态:
- 子类的对象可以看成父类的对像
- 父类引用 = 子类对象
-
Animal a = new Dog();
Java是强类型的语言,数据的类型和保存数据的变量的类型必须一致。
动物类型的引用只能保存动物类型的对象——狗是一种特殊的动物——狗类的对象也是动物类的对象——动物类型的引用可以保存狗类型的对象
多态的意义:
- 引用类型是一种主管类型
- 把对象视为什么类型就是什么类型
- 对象类型是一种客观类型
- 对象的真实类型,不会随着看法改变
-
Animal a = new Dog();
多态使用中的原则:
1.对象类型永远不变,变的是引用类型
2.只能对引用调用其引用类型中声明的方法
3.运行时会调用对象的实际类型中的方法
多态使用中的原则:
1.对象类型永远不变,变的是引用类型
- 对象一旦创建完成,它的类型就是确定的,不会发生改变。
- 同一个对象,可以放入任何一个它的父类型的引用中
2.只能引用调用其引用类型中声明的方法
- 父类中的方法子类也有,可以调用
- 子类有的方法父类不一定有,不可以调用
3.运行时会调用对象的实际类型中的方法。
- 如果子类覆盖了父类的方法,则会调用子类的方法
- 如果子类没有覆盖父类的方法,则会调用子类继承父类的方法的方法
1 class SuperClass{ 2 public void m1(){} 3 public void m2(){} 4 } 5 6 class SubClass extends SuperClass{ 7 public void m2(){} 8 public void m3(){} 9 }
main(){ SuperClass sc = new SubClass(); sc.m1(); //父类 sc.m2(); //子类 sc.m3(); //错误 }
多态的常见的用法:
- 引用使用多态
- 父类的引用指向子类的对象
- 不关心子类对象的个性,只关心对象的共性
- 对对象的调用方法,不同的对象会产生不同的结果
- 方法的形参使用多态
- 方法的声明中,使用父类类型作为形参类型——方法调用时,传递的实参是子类的对象——形参是方法内部有效的局部变量——父类的引用指向子类的对象
- 方法的返回值类型使用多态
- 方法的声明中,使用父类类型作为 返回值类型——方法执行后,返回子类对象——必须用父类类型的引用接收方法的返回值——父类的引用指向子类的对象
使用多态的好处:
子类和父类是特殊和一般的关系,把特殊的子类对象看成是一般的父类对象,可以屏蔽不同子类之间的差异,使程序更通用
多态的作用:
- 使对象之间为弱耦合性
- 提高代码的可扩展性
二、instanceo运算符
要调用子类对象特有的方法,需要把对象装入子类的引用中,把父类的对象赋给子类的引用,需要手动类型转换。
Animal a = new Dog(); Dog d = a; Dog d = (Dog)a;
上述代码违反了强类型
同一个父类的不同子类对象,都能使用父类的引用。
Animal a = new Cat(); Dog d = (Dog)a;
手动类型转换就是向编译器表明一种态度,转换的风险由程序员负责,所以编译器不会再检查程序是否合理,引用多态是运行时多态,再程序运行时才能发现程序中的问题,为了避免问题暴露的太迟,需要在编译时就发现运行时可能存在的问题
instanceof运算符:
- 是一个布尔运算符,结果为true或false
- 引用instanceof类
- 用来判断引用指向的对象是否属于某种类型
使用方法:
if (a instanceof Dog){ Dog d = (Dog)a; }
在手动类型转换前使用instanceof运算符判断,如果类型相同,则进行转换,否则不转换,这样运行时就不会出现问题了
注意:
- instanceof运算符不会获得对象的真实类型,如果一个对象属于一个类,那么也一定属于这个类的父类
三、类加载
Java程序运行过程中,所有数据都是保存在JVM中的,启动一个Java程序,必先启动JVM中的。
启动一个Java程序,必先启动JVM。
思考:类的信息保存在哪里?
类的信息全部保存在class文件中。
思考:JVM到哪里加载class文件?
JVM到CLASSPATH环境变量中加载class文件
思考:一个类需要加载几次?
JVM启动过程中,一个类只需要加载一次
什么是类加载
当JVM第一次使用一个类时,需要找到这个类对应的class文件。JVM通过CLASSPATH环境变量找到这个类对应的class文件,并把这个文件中包含的类的信息读入到JVM的内存过程,叫做类加载。在JVM启动过程中,一个类只会加载一次。
类加载的时机:
- 创建对象时
- 父类对象是子类对象的一部分,加载子类需要加载父类
- 只声明引用不需要类加载
四、初始代码块
什么是初始代码块?
在类中,可以定义一个代码块,不属于任何方法。
class Animal{ { System.out.println("init"); } }
初始代码块中的代码什么时候执行?
- 在创建对象之前执行
- 每创建一个对象都会执行一次
如果有代码想在构造方法之前执行,可以放在初始代码中

浙公网安备 33010602011771号