java基础学习 day43(多态,多态调用成员的特点和内存图)

1. 什么是多态
同类型的对象,表现出的多种形态

2. 多态的表现形式
父类类型 对象名称 = 子类对象;

3. 多态的前提

  • 有继承/实现关系
  • 有父类引用指向子类对象
    Fu f = new Zi ();
  • 有方法重写

4. 多态的好处

  • 使用父类作为参数,可以接收所有子类对象
  • 使用父类作为参数,和方法的调用者,可以根据传递对象的不同,调用不同对象的重写后的方法。
  • 体现多态的扩展性和便利

5. 多态中调用成员的特点

  • 变量调用:编译看左边,运行也看左边
    a. 编译看左边:javac编译代码的时候,会看左边的父类中有没有这个变量,如果有,编译成功,如果没有,编译失败
    b. 运行也看左边:java运行代码的时候,实际获取的就是左边父类中成员变量的值
  • 方法调用:编译看左边,运行看右边
    a. 编译看左边:javac编译代码的时候,会看左边的父类中有没有这个方法,如果有,编译成功,如果没有,编译失败。
    b. 运行看右边:java运行代码的时候,实际上运行的是子类中,已经重写过的方法。
  • 如何理解:

编译时:
Animal a = new Dog();
sout(a.name);
a.show();
现在是用a去调用变量和方法,而a是Animal类型的,所以不管是调用变量还是方法,默认都会从Animal这个类中去找,但先不会调用。

运行时:
成员变量:在子类的对象中,会把父类的成员变量也继承下来的。
父(Animal):name 子(Dog):name

对于Dog d = new Dog();
sout(d.name);
如果用Dog类型的d变量来调用name,他就会调用子类里的name

成员方法:如果子类对方法进行了重写,那么在虚方法表中是会把父类的方法进行覆盖的。

对于Animal a = new Dog();
a.show();
如果用Animal类型的a变量来调用show()方法,他是调用子类里的方法。

对于Dog d = new Dog();
d.show();
如果用Dog类型的d变量来调用show()方法,他也是会调用子类里的方法。

  • 多态调用成员的内存图
    在这里插入图片描述
  • java中,加载字节码文件的顺序,永远是先加载父类,然后再加载子类
  • 如果是用多态调用变量(即Animal a = new Dog();),会直接在堆内存中的对象当中看,从父类里面继承下来的变量里,有没有name,如果有,则编译成功,如果没有则编译失败,报错
  • 如果是用多态调用方法,会先去方法区中找父类的字节码文件中有没有show()方法,如果没有,则编译失败,报错。如果找到了,则继续去方法区中找子类的字节码文件中的show()方法,若找到了就调用这个子类的方法,若没找到,则调用父类的这个方法。
  • 如果没有用多态调用变量或方法(即Dog d = new Dog();),则按正常继承中访问成员变量或成员方法的规则去找

猜你喜欢

转载自blog.csdn.net/u011453680/article/details/129131879
今日推荐