多态之父子争权

来源:互联网 发布:华住酒店员工流失数据 编辑:程序博客网 时间:2024/06/05 14:49
 

多态之父子争权

--模范青蛙

 

在谈及这个问题之前,先说一下多态的三个前提条件:

1.存在类的继承

2.存在方法的重写

3.父类引用指向子类对象

很多童鞋在多态这一块儿存在一些疑虑:什么时候调用父类的东西呢?什么时候又是调用子类的东西呢?好迷茫。

针对这一问题,咱们来结合例子简单分析一下:

看下面的一个简单的例子

public class Test_02 {

public static void main(String[] args) {

Father f=new Son();

f.name="";

f.drink();

}

}

class Father{

String name;

public void drink(){

System.out.println("Father在喝酒");

}

}

class Son extends Father{

String name;

public void drink(){

System.out.println("Son在喝酒");

}

}

下面就以上代码进行分析:

首先来谈论一下:对象“f”调用的是子类的方法?还是父类的方法?

大家都知道,子类继承父类会继承父类的一切非私有的方法和属性,但是,当子类的方法与父类的方法重名时,父类的方法就会被覆盖,所以:如果是对象调用方法,调用的是子类的方法,或许有人问:当调用的是子类没有的方法呢?《那肯定是调用的从父类继承过来的方法了》。

接下来讨论一下:对象“f”调用的是子类的属性?还是父类的属性:

在讨论之前,我们可以先做两个小实验:

实验一:将父类中的name属性加上私有的访问权限(private)这时你会发现在main()方法中“f.name”会报编译时错误:意思就是没有访问权限《如图一:所示》

 

 

图一:

 

实验二:将子类中的name属性加上私有的访问权限(private)这时你会发现在main()方法中“f.name”没有报错误:意思就是可以访问《如图二:所示》

 

 

 

 

图二:

经过上面的两个小实验童鞋们应该知道这里的“f”调用的是谁的name谁属性了吧

下面来简单总结一下为什么出现以上情况:

如果子类里存在与父类同名的方法,就意味着父类的那个方法已经被覆盖掉了,系统就不可能把父类里的方法搬到子类里面去了。

但是,属性却不是这样的,尽管子类里定义了与父类相同的水属性,父类的属性依然不会被子类的属性覆盖。

所以继承属性和继承方法之间存在着差异性,所以对于一个引用类型的变量而言,当通过变量访问它所引用的对象的属性时,该属性的值取决于声明该变量时的类型。

当通过该变量调用它所引用的对象的方法时,该方法的行为取决于它所实际引用的对象的类型

最近一直有童鞋纠结这样一个问题:父类引用指向子类对象后,可以调用子类所特有的方法吗?

答案是否定的,下面是个人的看法:父类引用指向子类对象后,会把父类的属性和方法都加载到那个子类中去(当然如果子类存在和父类同名的方法,父类的方法就会被覆盖了),而这个引用始终是指向从父类加载过来的那些属性和(被子类重写的和没有重写的方法),因此,这个引用是无法调用子类中所特有的方法的。




 




0 0
原创粉丝点击