Java 具有保护类的继承

Java 具有保护类的继承,java,inheritance,Java,Inheritance,这是一个继承的代码示例,代码运行良好。我无法理解此代码的输出,请向我解释 class R { private void S1() { System.out.println("R:S1"); } protected void S2() { System.out.println("R:S2"); } protected void S1S2() { S1(); S2(); } } cl

这是一个继承的代码示例,代码运行良好。我无法理解此代码的输出,请向我解释

class R {
    private void S1() {
        System.out.println("R:S1");
    }

    protected void S2() {
        System.out.println("R:S2");
    }

    protected void S1S2() {
        S1();
        S2();
    }
}

class S extends R {
    private void S1() {
        System.out.println("S:S1");
    }

    protected void S2() {
        System.out.println("S:S2");
    }
}

public class Inheritance {
    public static void main(String srgs[]) {
        new S().S1S2();
    }
}
输出为:

R:S1
S:S2
为什么第一个调用是对R类'S1,而第二个调用是对S类'S2。

R.S1
是私有的,因此它不是多态调用,并且
S.S1
不会覆盖它

R.S2
受保护,因此
S.S2
会覆盖它,当您对
S2
的实例调用
S2
时(即使它只是静态地被称为
R
的实例),也会调用
S.S2

发件人:

在类C中声明的实例方法m1重写在类A中声明的另一个实例方法m2,前提是以下所有条件均为真:

  • C是a的一个子类

  • m1的签名是m2签名的子签名(§8.4.2)

  • 要么:

    • m2是公共的、受保护的,或在与C相同的包中声明了默认访问权限,或

    • m1覆盖方法m3(m3不同于m1,m3不同于m2),因此m3覆盖m2


请注意,m2不能是私有的。

在R中,S1是私有的,因此不能被重写。因此,在R#S1S2中对S1的调用总是调用R#S1。S中的S1是完全不相关的。[旁注:你需要更好的名字。]

但是S2不是私有的,所以它可以被重写——而且它是私有的


Java虚拟机可以从知道私有函数不能被重写中获得良好的性能增益。没有任何东西,即使是子类,也不应该受到类的私有细节的影响。

因此S.S2覆盖R.S2。这解释了为什么将R.S2的访问修饰符更改为私有将产生所需的结果。谢谢JonYes,我现在知道了。是的,我需要更好的名字。谢谢,梅因就在那里。不是家庭作业。