2017-07-11 3 views
3

は、なぜ私は、クラスAまたはBのいずれかから年齢メソッドにアクセスすることはできませんか?私はそれが保護されたメソッドだと思った、派生クラスのインスタンスはそれを使用できる必要がありますか?派生クラスの使用による親メソッド

class Program 
{ 
    public static void Main(string[] args) 
    { 



    } 

    public static void Test(A test) 
    { 
     A a = new A(); 
     B b = new B(); 

     Console.WriteLine(a.Age()); 
     Console.WriteLine(b.Age()); 
    } 
} 

public class A 
{ 
    public virtual string Name { get { return "TestA"; } } 
    protected string Age() { return "25";} 
} 

public class B : A 
{ 

    public override string Name { get { return "TestB"; } } 
    public string Address { get; set; } 
} 

---ジョンSkeet--によって示唆されるように保護

public class B : A 
{ 

    public override string Name { get { return "TestB"; } } 
    public string Address { get; set; } 

    public void Testing() 
    { 
     B a = new B(); 
     a.Age(); 
    } 
} 
+0

保護された修飾子を使用すると、保護されたメソッドにアクセスすることはできません。 –

+1

派生クラスのインスタンスは保護されたメソッドにアクセスできますが、この場合は、それらのクラスでは何もしなくてはなりません。そのため、パブリックメソッドと変数だけがそこからアクセスできます。クラスBのインスタンスを使用してAgeメソッドを使用する場合は、それをpublicとしてオーバーライドして実装を行います。 –

答えて

5

は、派生クラスのコードから使用することができることを意味する - それは、外部から」使用することができるというわけではありません"派生クラスを扱うときに。

protected修飾子は、派生クラスであっても、独自のクラス(またはそれ以上の派生クラス)のインスタンスを介して保護されたメンバーにしかアクセスできないため、ややこしいことがあります。

だから、Bのコードの中に、あなたが書くことができる:

A a = new A(); 
Console.WriteLine(a.Age()); // Invalid - not an instance of B 
B b = new B(); 
Console.WriteLine(b.Age()); // Valid - an instance of B 
A ba = b; 
Console.WriteLine(ba.Age()); // Invalid 

でも、実行時にそれがBのインスタンス上のメンバーにアクセスだが、コンパイラは唯一baを知っているので、これらの最後が無効ですタイプはAです。

ここで物事を明確にすることができるC#5仕様のセクション3.5.3の開始、次のとおり

protectedインスタンス部材は、それが宣言されたクラスのプログラムテキストの外側にアクセスするときとprotected internalインスタンスメンバが宣言されているプログラムのプログラムテキストの外部でアクセスされた場合、宣言されているクラスから派生したクラス宣言内でアクセスする必要があります。さらに、アクセスは、からの派生クラス型のインスタンスまたはそれから構築されたクラス型を実行する必要があります。この制限により、メンバーが同じ基本クラスから継承されている場合でも、ある派生クラスが他の派生クラスのメンバーprotectedにアクセスできなくなります。

+0

ありがとう、Great Jon Skeet!私は自分の答えを更新し、それがあなたが言っていることを確認したかっただけで、保護されたメンバーにアクセスする唯一のオプションです。 – Baahubali

+0

@Baahubali:あなたが保護されたメンバーにアクセスしたい場合はまあ、はい、それはこれらのルールに従わなければならない...それは中*だとして 'テスト()'メソッドは、新しいインスタンスを作成せず ')('年齢を呼び出すことができますが、 * Bのインスタンス。 (これは 'B.Age()'と同等です)。 –

関連する問題