Java关于子类对父类私有方法覆盖的问题

来源:互联网 发布:js隐藏网页源代码 编辑:程序博客网 时间:2024/06/05 15:08

最近在学习到Java的继承和多态时遇到了这样的一个问题:关于继承链中子类对父类的私有方法是否可以覆盖的问题,在此记录一下自己对这个问题解决以后的一些心得。

首先要明确:子类是不能够覆盖(重写)父类的私有方法的。比较直观的理由是,子类要能够重写父类的方法的前提条件是继承,子类对父类的私有方法并不继承,也没有访问权限,自然也是不能重写的。接下来看一个例子:

[java] view plain copy
  1. <span style="font-size:14px;">public class Test {  
  2.     public static void main(String[] args) {  
  3.         new A().printPerson();  
  4.         new B().printPerson();  
  5.     }  
  6. }  
  7.   
  8. class A {  
  9.     public void printPerson() {  
  10.         System.out.println(getInfo());  
  11.     }  
  12.     private String getInfo() {  
  13.         return "A";  
  14.     }  
  15. }  
  16.   
  17. class B extends A{  
  18.     public String getInfo() {  
  19.         return "B";  
  20.     }  
  21. }</span>  
运行结果是 A A。如果将private修饰词去掉,换成protected和public修饰,运行结果是A B这是毫无疑问的,因为那正是B重写了父类A的getInfo方法;而加上了private修饰词以后,父类A的getInfo和子类B的getInfo实际上就是两个无关的方法,因为私有方法是不能被子类重写的,私有方法并不是父类接口的一部分,只是隐藏在父类中的一段程序代码。

可是为什么使用子类B的实例调用printPerson,结果是打印A呢?要注意到printPerson方法是在父类A中定义的,因此刚执行new B().printPerson()这行代码时,编译器在子类B中无法找到匹配的printPerson方法,于是到父类A中去寻找;此时在父类A中找到了匹配的printPerson方法,并调用该方法。

此处需要提及一下子类在继承父类时对父类的成员变量及方法继承的问题。对于使用protected或者public修饰的成员变量及方法,会被子类继承,且可通过子类直接调用,那么,对于子类不可见的private成员,以及没有修饰词修饰的成员(若子类与父类在不同的包中,这一类成员也是对子类不可见的),他们不被子类继承,那么在子类的实例所代表的内存空间中,这些成员是否存在呢?答案是肯定的,父类的私有变量及方法虽然不会被子类继承,对于子类来说不可见,但当创建了子类的实例的时候,这些成员一样会被加载入内存,并“隐藏”在内存当中。

因此,通过子类B的实例调用printPerson方法,会在父类的成员中寻找匹配的printPerson方法,找到以后,进入printPerson的方法体,调用getInfo方法,程序回到上层去寻找getInfo方法的匹配,并在内存空间中寻找到了A中的getInfo方法,同时由于该getInfo方法是私有的,无法被重写,因此不会触发java的动态绑定机制,于是直接调用该方法。因此,通过B的实例调用printPerson,打印的结果也是A了。

阅读全文
0 0