日期:2014-05-20  浏览次数:20770 次

关于争议继承父类私有成员问题!欢迎斧正 !
子类继承父类私有方法的证明 附:子类如何调用父类的私有方法
“子类不能继承父类的私有成员,私有方法不能被子类访问” ,是一个比较流行的说法 。事实果真如此么?事实正好相反。
      经考证研究:私有成员是必须被子类继承的;子类也可访问父类的私有成员(利用java反射)。如果您还表示怀疑的话,请亲自运行如下的代码,下面的代码实现子类对象调用父类的私有方法,能够说明标题上的命题是不完全正确的。
      A.java代码如下: 
package com.lyh.test;
public class A {
    private int x=100;
    protected A(){}
    private int getXxx() //求平方函数
    {  return x*x; }
}

        B.java代码如下:
package com.lyh.test;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class B extends A {
    public B(){  super(); }
    private int y=200;
    //下面的函数调用父类的私有方法getXxx()  ,绿色部分附加了子类修改继承下来的私有字段的代码 。
    public void callParentPrivate() throws SecurityException, NoSuchMethodException, IllegalArgumentExceptionIllegalAccessExceptionInvocationTargetException, NoSuchFieldException
    {

        /******************************************/
        Field xxx = A.class.getDeclaredField("x");//取得父类私有字段的封装对象
        xxx.setAccessible(true);//设置强制访问
        xxx.set(this,20);//改变私有字段值。注意:这里的this代表B类将来的对象
        /******************************************/
        //以上绿色区域可以省略,仅仅键入下面的砖红色代码足以证明私有方法被继承下来了。
      //1、取得父类私有方法的对象
        Method m = A.class.getDeclaredMethod("getXxx", new Class[]{});

        //2、强制访问私有方法
        m.setAccessible(true);

        //3、通过本子类对象调用之
        Object ret = m.invoke(this, new Object[]{}); //注意:this代表B类的对象 ,这一句的意思:在B类对象上调用方法m (m封装了getXxx) 。
        System.out.println(ret);
    }
    
}

R.java 含有main方法的测试类:
package com.lyh.test;
import java.lang.reflect.InvocationTargetException;
public class R {
    public static void main(String[] args) throws ClassNotFoundException, SecurityException, NoSuchFieldException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        //子类对象调用父类私有函数演示
        B b = new B();
        b.callParentPrivate();                
    }

}

运行结果:
无绿色代码时:10000
有绿色代码时:400 

结论:

        经过归纳总结,正确的此范畴命题是:“子类继承父类的除构造方法以外的一切成员;子类不能直接调用父类的私有方法、但是可以通过反射调用它们。” 。本文重点:通过实验证明“子类继承了父类的私有成员”。
        
        上述内容 ,欢迎斧正 。