A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

在我学习多态的过程中,我碰见父类对象引用指向子类对象实体的情况,
  1. Father obj = new Son();
复制代码

为此,我对于其调用哪些方法以及的其具体的结构产生的一些疑问,
下面是我的一些看法。
一般的创建对象是是这样的

  1. Class obj = new Class();
复制代码

这两段代码唯一的区别就是new 后面的代码不同。
下面是我的一些看法:
一般的创建对象,是在栈空间中声明一个变量,这和普通基本数据类型变量相似,
第二段代码:
“=”左边:在栈空间中声明一个Class类型的变量,变量名是obj,变量所记录的的是首地址,
“=”右边:变量的首地址指向了它 的实例化,内容是Class类的成员。
用obj对象调用方法,其实是调用Class类的成员方法。

接下类看第一段代码:
“=”左边:在栈空间中声明一个Father类型的变量,变量名是obj,变量所记录的的是首地址,
“=”右边:变量的首地址却是指向子类的实体对象。
那么问题来了,调用的方法是谁的呢?我做了一些测试
  1. class Parent {
  2.         String name;
  3.         int age;
  4.        
  5.         public void print(){
  6.                 System.out.println("parent");
  7.         }

  8. }
  9. class Son extends Parent{
  10.         int a = 1;
  11.         public void print(){
  12.                 System.out.println("son");
  13.         }
  14.         public void show(){
  15.                 System.out.println("sonshow");
  16.         }
  17. }
  18. class Goon{
  19.         public static void main(String[] args) {
  20.                 Parent p = new Son();
  21.                 p.print();
  22.         }
  23. }
复制代码

运行的结果:子类的方法结果

但是把子类重写的方法注释掉呢:
那么结果是父类的。那么试下调用子类特有的方法,结果是编译报错。

这样我就有思路了:
在父类对象引用指向子类对象实体的时候,调用的是子类的成员,
因为子类继承了父类的成员,所以才能调用。
但是因为变量的父类类型的,所以只能调用子类继承的父类的成员,而不能调用子类所特有的成员

那么又有一个问题了——为什么调用print()方法时候结果显示子类的结果呢?是不是调用子类的的方法呢?
答案是:是的。
这是为什么呢?
那是因为子类重写了父类的print()方法,当试图调用子类所继承的父类的print()方法时,,它被“挡住了“。
子类重写父类方法时,其实已经覆盖了父类被重写的方法
所以,在这种多态的情况下,
对象引用只能调用子类中父类已经声明的成员。




0 个回复

您需要登录后才可以回帖 登录 | 加入黑马