web-dev-qa-db-ja.com

プライベートメンバーはC#で継承されますか?

それを言っている1つのチュートリアルを見ました:

Class Dog
{
  private string Name;
}
Class SuperDog:Dog
{
 private string Mood;
}

次に、SuperDogがNameも継承することを示すUMLがありました。私は試しましたが、私にはパブリックメンバーのみが継承されているようです。少なくとも、パブリックとして宣言されていない限り、Nameにアクセスできませんでした。

57
Petr

派生クラスは、基本クラスのpublic、protected、internal、およびprotected内部メンバーにアクセスできます。派生クラスは基本クラスのプライベートメンバーを継承しますが、それらのメンバーにアクセスすることはできません。ただし、これらのプライベートメンバーはすべて派生クラスに存在し、基本クラス自体で実行するのと同じ作業を実行できます。たとえば、保護された基本クラスメソッドがプライベートフィールドにアクセスするとします。継承された基本クラスメソッドが適切に機能するためには、そのフィールドが派生クラスに存在する必要があります。

From: http://msdn.Microsoft.com/en-us/library/ms173149.aspx

技術的には、そうですが、実際にはそうではありません。

102
Martin Eve

基本クラスのすべてが派生クラスに継承されます。 privateとマークされたメンバーは、整合性のために派生クラスにアクセスできません。派生クラスでアクセスできるようにする必要がある場合、メンバーを保護としてマークします。

継承のコンテキストには、メンバーのアクセシビリティのさまざまなレベルがあります。

public:基本クラスのすべてのパブリックメンバーは、派生クラス内および派生クラスのインスタンスにアクセスできます。

protected:基底クラスのすべての保護されたメンバーは、派生クラスのインスタンスからではなく、派生クラス内でアクセスできます。

protected internal:基本クラスのすべての保護された内部メンバーは、派生クラス内および同じアセンブリ内で作成された派生クラスのインスタンスにアクセスできます。

internal:基本クラスのすべての内部メンバーは、派生クラス内および同じアセンブリ内の派生クラスのインスタンスにアクセスできます。

private:派生クラス内および派生クラスのインスタンスにアクセスできる基本クラスのプライベートメンバーはありません。

44

はい、SuperDogはNameフィールドを継承します。

SuperDogは[〜#〜] not [〜#〜]にフィールドへのアクセス権を持っているため、実用的ではありません(SuperDogに関する限り)。

18
Justin Niessner

プライベートメンバーは、派生クラス内で表示可能です(サブクラスが基本クラス内にネストされている場合)

public class Person
{
    private string message;

    public override string ToString()
    {
        return message;
    }

    public static Person CreateEmployee()
    {
        return new Employee();
    }

    class Employee : Person
    {
        public Employee()
        {
            this.message = "I inherit private members!";
        }
    }
}

この例の功績は KodefuGur in このMSDNのスレッド にあります。

2
Jørgen Fogh

はい、ただしheirsはアクセスできませんそのメンバー。

それであなたが彼らにアクセスできるようになるなら、それをprotectedとして宣言してください。

1
Poni

いいえ、そうではありません。

protected修飾子は、派生クラスでフィールドを使用可能にすることができますが、これは一般的にメンテナンスの観点からは悪い考えと見なされます。代わりに、保護されたプロパティを使用する必要があります。

1
Warren Rumak

はい、継承されます。しかし、それらはプライベートなのでアクセスできません:)。

0
Ram

プライベートメンバーは、クラスの子孫にはアクセスできません。

すべてのアクセス修飾子がわかりませんが、最も基本的なのはパブリックメンバーと保護されたメンバーだけがアクセスできることです。

0
Matt Ellen

基本クラスのメンバーは、派生クラスで表示できるように、少なくとも保護する必要があります。

0
Petar Minchev

public/privateではなく、protectedキーワードを試してください。

http://msdn.Microsoft.com/en-us/library/bcd5672a(VS.71).aspx

0
dm76

代わりにName protectedまたはpublicを作成すると、アクセス可能になります。プライベートクラスは派生クラスからアクセスできません

0
Greg Olmstead

人々はそれを言っていますが、派生クラスにプライベートフィールドが必要な理由の例を次に示します。

class Program
{
    static void Main(string[] args)
    {
        var r = new Random();

        foreach(var i in Enumerable.Range(0,100))            
            new Derived(r).Printer();            

        Console.Read();
    }
}

public class Base
{
    private Random r;
    public Base(Random r) { this.r = r; }

    protected void Print()
    {
        Console.WriteLine(r.Next(1, 10000));
    }
}

public class Derived : Base
{
    public Derived(Random r) : base(r) { }
    public void Printer()
    {
        base.Print();
    }
}
0
Jonesopolis

他の人が言ったように、プライベートメンバーは継承されます。メンバーアクセスは別の主題ですが、継承の観点から完全にばらばらではありません。すべてのメンバーは、サブクラスのサイズに影響するため、アクセス修飾子に関係なく継承されることを理解することが重要です。次のコードを検討してください。

public class Foo
{
  private int a;
  public int b;
}

public class Bar : Foo
{
  private int c;
  public int d;
}

Fooは、ヒープで16バイトを消費します。同期ブロックの場合は4、型情報(メソッドテーブル)の場合は4、合計12のint変数の場合はそれぞれ4です。一方、Barは24バイトを消費します。 syncblockの場合は4、タイプ情報(メソッドテーブル)の場合は4、intから継承されたFooフィールドには4、_intBarフィールドには4合計24個。

0
Brian Gideon

はい、しかしそれらはアクセス可能ではないので、それを見ると、それらは継承されていないと正直に言うことができます。しかし、はい、彼らは本当に

0
Spooks