17

Javaサブクラスの場合、そのスーパークラスのすべてのメンバーを継承できると言われました。それで、これは私的なメンバーでさえ意味するのでしょうか?保護されたメンバーを継承できることは知っています。

誰かが私にこれを説明できますか?私は今完全に混乱しています。

4

5 に答える 5

29

いいえ、プライベートメンバーのスコープは、それが定義されているクラスにのみ制限されているため、プライベートメンバーは継承されません。パブリックメンバーと保護されたメンバーのみが継承されます。

からJava Documentation

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

サブクラスは、その親クラスのプライベートメンバーを継承しません。ただし、スーパークラスにプライベートフィールドにアクセスするためのパブリックメソッドまたはプロテクトメソッドがある場合、これらはサブクラスでも使用できます。ネストされたクラスは、それを囲むクラスのすべてのプライベートメンバー(フィールドとメソッドの両方)にアクセスできます。したがって、サブクラスによって継承されたパブリックまたは保護されたネストされたクラスは、スーパークラスのすべてのプライベートメンバーに間接的にアクセスできます。

からJLS

プライベートとして宣言されたクラスのメンバーは、そのクラスのサブクラスに継承されません。保護またはパブリックと宣言されたクラスのメンバーのみが、クラスが宣言されたパッケージ以外のパッケージで宣言されたサブクラスによって継承されます。

便利なリンク:サブクラスはプライベートフィールドを継承しますか?

于 2011-07-01T03:38:49.467 に答える
29

この種は、継承という言葉の正確な使用法によって異なります。例を挙げて説明します。

2つのクラスがあるとします:ParentChild、ここで、Childextends Parent。また、Parentという名前のプライベート整数がありvalueます。

ここで質問があります:Childプライベートを継承しvalueますか?Javaでは、継承は答えが「いいえ」になるように定義されます。ただし、一般的なOOP用語では、わずかなあいまいさがあります。

を明示的に参照できる場所がないため、継承されていないと言えます。つまり、のようなコードは、内で使用することも、一部の呼び出しコードから使用することもできません(明らかに)。Childvaluethis.valueChildobj.value

しかし、別の意味では、それvalue 継承されていると言えます。Childのすべてのインスタンスがのインスタンスでもあると考える場合Parent、そのオブジェクトにはで定義されているとおりに含まれている必要があります。クラスがそれについて何も知らなくても、という名前のプライベートメンバーは、のすべてのインスタンス内に存在します。したがって、この意味で、それはに継承されていると言えます。valueParentChildvalueChildvalueChild

したがって、「継承」という言葉を使用せずに、子クラスは親クラス内で定義されたプライベートメンバーについて知らないことを覚えておいてください。ただし、これらのプライベートメンバーは、子クラスのインスタンス内にまだ存在していることも覚えておいてください。

于 2011-07-01T03:50:57.613 に答える
5

ここで100%満足します。私は自分のコンピューターでそれをテストし、私が結論したことはここに投稿するつもりです。以下に書かれているプログラムに目を通し、プログラムの出力を見て、最後にある結論を読んでください。自分でテストするには、プログラム全体をコピーして「InheritanceTest.java」という名前のファイルに保存し、コンパイルして最後に実行します。

プログラム

// Testing if a subclass can access the private members of a superclass

class Class1 {
    private String name;

    public void setName(String name) {
        this.name = name;
        System.out.println("The name has been set successfully.");
    }

    public void showName() {
        System.out.println("The name is: " + name);
    }
}

class Class2 extends Class1 {
    private int age;

    public void setAge(int age) {
        this.age = age;
        System.out.println("The age has been set successfully.");
    }

    public void showAge() {
        System.out.println("The age is: " + age);
    }

    public void displayName() {
        //Accessing the private member of superclass here
        //System.out.println("The name is: " + name); //error, can't compile because access to the private member name of the superclass Class1 is not permitted here.
    }
}

class InheritanceTest {
    public static void main(String[] args) {

        Class1 c1 = new Class1();
        Class2 c2 = new Class2();

        c1.setName("Name_C1");
        c2.setName("Name_C2"); //No error, setName() is a public member of the superclass which indirectly gives access to the private member "name".

        c1.showName();
        c2.showName(); //No error, showName() is a public member of the superclass which indirectly gives access to the private member "name".

        c2.setAge(25);
        c2.showAge();

        //c2.displayName(); //error
    }
}

出力

The name has been set successfully.
The name has been set successfully.
The name is: Name_C1
The name is: Name_C2
The age has been set successfully.
The age is: 25

結論

はい、サブクラスはスーパークラスのプライベートメンバーに間接的にアクセスできます。サブクラスは、スーパークラスのプライベートメンバーに直接アクセスすることはできません。

スーパークラスのすべてのパブリック、プライベート、および保護されたメンバー(つまり、すべてのフィールドとメソッド)はサブクラスによって継承されますが、サブクラスはスーパークラスのパブリックおよび保護されたメンバーにのみ直接アクセスできます。スーパークラスから継承されたメンバーがスーパークラスのプライベートメンバーへのアクセスを許可する場合、サブクラスはこの継承されたメンバーを使用してスーパークラスのプライベートメンバーにアクセスできます。

于 2018-11-03T11:11:07.023 に答える
3

IMOは決して定義の問題ではありません。クラスベースの継承では、子孫への動作の伝播を意味します。そのようなプライベートメンバーは継承されますので、これがどのように発生するかについては詳しく説明しません。

実際、「継承されない」という答えは新しい開発者にとって危険であると思います。彼らは、プライベートメンバーがクラスのスキンの下に隠されていることをすぐには理解せず、その動作やサイズに深刻な影響を与える可能性があります。オブジェクトなど。

コンピュータサイエンスでは「開発は理解の前に来る」のが一般的ですが、よく知られているクラスベースのオブジェクト指向プラットフォームのマニュアルを作成する技術者が誤った「定義」を採用したと仮定して、OOPの概念を構築(または破壊)しないようにします。

そのような古い投稿に何かを述べて申し訳ありませんが、問題は常に有効です。

于 2012-04-27T18:11:33.703 に答える
2

https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2は、プライベートメンバーが継承されていないことを示していますが。実際には、サブクラスに継承されます。デバッガーを使用して変数をトレースすると、「継承された」というラベルの下にプライベートメンバーが表示されるので、試してみてください。この質問について議論している別の投稿があり、それらのほとんどは継承されていないと考えています。これは、最初は私を含む多くの人々を誤解させます。

于 2018-07-28T00:15:29.573 に答える