Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么强制转换为父类型的子类默认为私有实例方法的父版本,而不是其他实例方法的父版本?_Java_Inheritance - Fatal编程技术网

Java 为什么强制转换为父类型的子类默认为私有实例方法的父版本,而不是其他实例方法的父版本?

Java 为什么强制转换为父类型的子类默认为私有实例方法的父版本,而不是其他实例方法的父版本?,java,inheritance,Java,Inheritance,我的理解是,对父类型的子类型转换(如Super sc=new child();)将调用父类的静态方法,并访问父类的非隐藏字段,但将使用子类的实例方法 对于私有实例方法(由于父方法是私有的,所以实际上不会发生重写的方法)来说,这似乎不成立 我理解没有重写(私有父方法对子对象不可见,因此只能隐藏它们)这一事实意味着,当从子对象调用实例方法时,子对象不会查找继承权以查看父对象的方法版本。 然而,与我所期望的完全相反的情况(在被调用的孩子中出现的版本)正在发生。调用私有方法的父版本 如果子类的实例方法通

我的理解是,对父类型的子类型转换(如
Super sc=new child();
)将调用父类的静态方法,并访问父类的非隐藏字段,但将使用子类的实例方法

对于私有实例方法(由于父方法是私有的,所以实际上不会发生重写的方法)来说,这似乎不成立

我理解没有重写(私有父方法对子对象不可见,因此只能隐藏它们)这一事实意味着,当从子对象调用实例方法时,子对象不会查找继承权以查看父对象的方法版本。
然而,与我所期望的完全相反的情况(在被调用的孩子中出现的版本)正在发生。调用私有方法的父版本

如果子类的实例方法通常被调用,并且在子类中已经存在一个具有相同签名(在本例中与调用
method2()
完全匹配)的方法,并且在父类中隐藏了相同的方法,那么为什么会发生这种情况

package whatever;

public class A {

    public void method1(){
        System.out.println("A method1().");
    }
    //using "final" here to emphasize that this is a hiding, not an override. 
    private final void method2(){  
        System.out.println("A private method2().");
    }

    public static void main(String[] args)
    {
        A a = new A().new B();
        a.method1(); //calls B  method 1
        ((A.B)a).method1(); //calls B method 1 
        a.method2(); //calls A private method 2 **I expected it to call B private method 2
        ((A.B)a).method2(); //calls B private method 2

    }

    public class B extends A {

        public void method1(){
            System.out.println("B method1().");
        }
        private final void method2(){
            System.out.println("B private method2().");
        }
    }

}

简短回答:因为您的
B类
与包含
#main()
方法的类位于同一个文件(.java)中。

父类的私有方法对子类可见的原因是,在您的情况下,子类是其父类的私有方法

非静态嵌套类(内部类)可以访问封闭类的其他成员,即使它们声明为私有


首先,B实际上是一个嵌套类,奇怪的是,外部类可以访问嵌套类的私有成员。否则,执行
((A.B)A.method2())甚至是不合法的(反之亦然。B也可以访问A中的私有成员。)

也就是说,要回答您的实际问题,原因是
a.method2()调用中的私有方法是因为私有方法不是虚拟的,因为它们根本不能被重写。(如果继承类甚至不应该知道它们,它们怎么可能呢?)
A
声明为A,但
(A.B)A
在编译时被强制转换为B。因此,第一次调用使用A的私有方法,第二次调用使用B的私有方法

奇怪的是,这两段中的事实并没有相互影响。可以合理地预期,由于嵌套类“知道”外部类的私有成员,因此可以进行重写。但事实并非如此。私有函数永远不会显示在vTable中,也永远不会被重写