编程日记: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");
    }  
}

初始代码块中的代码什么时候执行?

  • 在创建对象之前执行
  • 每创建一个对象都会执行一次

如果有代码想在构造方法之前执行,可以放在初始代码中

posted @ 2021-11-29 15:42  MachineHe  阅读(43)  评论(0)    收藏  举报