1

これは、コードが正常に機能している間の継承のコードサンプルです。このコードの出力を理解できません。親切に説明してください。

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に対して2番目の呼び出しが行われるのはなぜですか。

4

2 に答える 2

3

R.S1プライベートであるため、多形的には呼び出されず、S.S1オーバーライドされません。

R.S2保護されているため、S.S2オーバーライドします。のインスタンスを呼び出すS2S2静的にのインスタンスであることがわかっている場合でもR)、S.S2が呼び出されます。

JLSのセクション8.4.8.1から:

クラスCで宣言されたインスタンスメソッドm1は、次のすべてが当てはまる場合に、クラスAで宣言された別のインスタンスメソッドm2をオーバーライドします。

  • CはAのサブクラスです。

  • m1の署名は、m2の署名のサブ署名(§8.4.2)です。

  • また:

    • m2はパブリック、保護、または宣言されており、Cと同じパッケージでデフォルトのアクセス権があります。

    • m1はメソッドm3(m1とは異なるm3、m2とは異なるm3)をオーバーライドし、m3はm2をオーバーライドします。

m2プライベートにすることはできないことに注意してください。

于 2012-08-10T20:08:42.283 に答える
0

R では、S1 はプライベートであるため、オーバーライドできません。したがって、R#S1S2 で S1 を呼び出すと、常に R#S1 が呼び出されます。S の S1 はまったく無関係です。[補足: より良い名前が必要です。]

しかし、S2 はプライベートではないため、オーバーライドできます。

Java VM は、プライベート関数をオーバーライドできないことを理解することで、パフォーマンスを大幅に向上させることができます。また、クラスのプライベートな詳細によって影響を受けるものは、たとえ子孫クラスであってもありません。

于 2012-08-10T20:13:51.310 に答える