5

私のような質問が見つからなかったので、重複していないことを願っています。

繰り返しますが、オーバーライドと非表示についてです。と思いますが、間違っているかもしれませんが、どちらも理解できました。

次のコードは期待どおりに動作します。両方のメソッドが非表示になっています。method1 はプライベート メソッドであり、プライベート メソッドは非表示にしかオーバーライドできないため、method2 は静的であり、静的メソッドはオーバーライドできないため、非表示にしかできないためです。

public class Child extends Parent { 
    public void method1(){System.out.println("child");}     
    public static void method2(){ System.out.println("static child");}  
}

class Parent{
    private void method1(){ System.out.println("parent");}      
    public static void method2(){ System.out.println("static parent");}

    public static void main(String[] args){
            Parent p = new Child();
            p.method1(); //prints out "parent"
            p.method2(); //prints out "static parent"
    }
}

仕様を読むと、次のように書かれています。

http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.3.3

サブクラスがメソッドをオーバーライドまたは非表示にしないように、メソッドを final として宣言できます。

Parent クラスの method1 を「final」に変更すると

private final void method1(){ System.out.println("parent");}

すべて正常に動作します。edit start: final メソッドを非表示にできないというコンパイラ エラーが発生することを予期していましたが、そうはなりませんでした。:編集終了

質問 1: 静的メソッドのみを非表示にできるということですか? 私が読んでいる本 (OCA 学習ガイド、Jeanne Boyarsky と Scott Selikoff の 252 ページ) では、私的な方法が隠されていると明確に述べています。

次に、Parent クラスの method2 を次のように変更しました。

public final static void method2(){ System.out.println("static parent");}

現在、コンパイラは文句を言いますが、「子は method2() をオーバーライドできません」というエラーが表示されます。これは、メソッドを隠そうとしたと思ったため、かなり混乱しています。

質問 2: 「子は method2() を非表示にできない」ではないでしょうか?

編集開始:ここではオーバーライドが行われないことをよく知っていますが、前述の仕様が指摘しているように:修飾子 final はメソッドがオーバーライドまたは非表示になるのを防ぎます。そのため、タイトルに入れました。:編集終了

4

2 に答える 2

8

質問1

質問 1: 静的メソッドのみを非表示にできるということですか?

Parent.method1()Child存在するという理由だけで目に見えることも継承されることもありませんでしたprivate。したがって、Child.method1()オーバーライドも非表示もせず、同じ名前、パラメーター、および戻り値の型をParent.method1()持つ新しいメソッドを作成しただけです。Child

http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.8.3を参照してください:

これらの用語の技術的な意味では、プライベート メソッドを非表示にしたりオーバーライドしたりできないことに注意してください。これは、サブクラスがそのスーパークラスの 1 つでプライベート メソッドと同じシグネチャを持つメソッドを宣言できることを意味し、そのようなメソッドの戻り値の型または throws 句が、スーパークラス。

質問2

質問 2: 「子は method2() を非表示にできない」ではないでしょうか?

はい。それで合っています。「非表示」にする必要があります。JLS ( http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.8.2 ) に従って、

クラス C が静的メソッド m を宣言または継承する場合、m は任意のメソッド m' を隠すと言われます。ここで、m の署名は、m' の署名のサブ署名 (§8.4.2) です。それ以外の場合は C のコードにアクセスできる C。

「隠す」とは、staticメソッドがメソッドに対して行うことstaticです。「オーバーライド」とは、インスタンス メソッドがインスタンス メソッドに対して行うことです。2 つを混在させるstaticことはできません。メソッドはインスタンス メソッドをオーバーライドまたは非表示にすることはできず、インスタンス メソッドはメソッドをオーバーライドまたは非表示にすることはできませんstatic

ところで、私のEclipseコンパイラは同様のエラーメッセージを出します:「親からの最終メソッドをオーバーライドできません」

于 2016-02-03T14:13:42.677 に答える
2

まあ、私はJavaにはまったく慣れていませんが、答えようとします。

違いは、異なるアクセス レベル修飾子を使用しているという事実にあります。method1()親クラスのプライベートとmethod1()子クラスのパブリックを使用しています。実際、同じメソッドではないため、メソッドを隠しているわけではありません。private 修飾子は、メンバーが独自のクラスでのみアクセスできることを指定しているため、method1()Child クラスで宣言するときに新しいメソッドを使用しています。child は Parent からすべてのメソッドを継承します (継承するため) が、プライベート メソッドは継承されません。の場合、method2()宣言されている通りpublic、Child クラスに継承され、非表示にすることができます。

それについての詳細(Oracleチュートリアルから取得):

スーパークラスのプライベート メンバー

サブクラスは、親クラスのプライベート メンバーを継承しません。ただし、スーパークラスにプライベート フィールドにアクセスするためのパブリック メソッドまたはプロテクト メソッドがある場合、これらはサブクラスでも使用できます。

ネストされたクラスは、それを囲むクラスのすべてのプライベート メンバー (フィールドとメソッドの両方) にアクセスできます。したがって、サブクラスによって継承されたパブリックまたは保護されたネストされたクラスは、スーパークラスのすべてのプライベート メンバーに間接的にアクセスできます。

編集済み:質問2:

最終的なメソッドではなく、静的メソッドを非表示にします。次のように、静的なもののみを非表示にできます。

class SuperClass {
    static void display() {
        System.out.println("Super");
    }
}

class SubClass extends SuperClass {
    static void display() {
        System.out.println("Sub");
    }
}

public class Test {
    public static void main(String[] args) {
        // Prints "Super" in console
        SuperClass sup = new SubClass();
        sup.display();

        // Prints "Sub" in console
        SubClass sub = new SubClass();
        sub.display();
    }
}

メソッド宣言で final キーワードを使用して、メソッドをサブクラスでオーバーライドできないことを示します。したがって、変更するとオーバーライドされるため、コンパイラは次のように言います。

overridden method is static,final( に注意してfinalください)。

あなたはもはやそれを隠していないので、コンパイラはそれについて不平を言います。あなたがそれを宣言したようにfinal、あなたはそれをオーバーライドしています。staticChild クラスで修飾子を使用しないと、それがもはや存在しないものをオーバーライドしようとするため、同じエラーが発生しますstatic。非表示は、静的メソッドが別の静的メソッドを非表示にする場合にのみ使用されます。試してみると:

  1. 非静的メソッドは静的メソッドを「非表示」にします。つまり、オーバーライドです。
  2. final メソッドは静的メソッドを「非表示」にします。つまり、オーバーライドです。

そのような場合、もう非表示にしようとはしていませんが (非表示は静的にのみ使用されるため)、オーバーライドしようとしています。

于 2016-02-03T14:28:01.877 に答える