2

C#仕様には次のように記載されています。

基本クラスメンバーの宣言されたアクセシビリティは、メンバーが継承されるかどうかを制御しません。継承は、インスタンスコンストラクター、静的コンストラクター、またはデストラクタではないメンバーに拡張されます。ただし、継承されたメンバーは、宣言されたアクセシビリティのため、または型自体の宣言によって隠されているため、派生型ではアクセスできない場合があります。

アクセスできないメンバーが継承されたと見なされるのはなぜですか?なぜそのような区別がなされた/実用的なのですか?

具体例として

class A
{
    const string foo = "c";

    internal void DoWork() { }
}

class B: A
{
    const string bar = "d";//renamed to foo does not appear to have a noticeable impact
    B() { bar = foo; }//inaccessible due to protection level

    internal new void DoWork() { }//hide inherited member
}

私の考えでは、実行時の継承とは、状態や動作を共有することを意味します。そのfooようなことは起こりません。

Bの振る舞いを継承するかどうかはあなた次第ですDoWork()。したがって、DoWork()のメンバーになることBは直感的で関連性があります。一方、なぜfooのメンバーとして扱われるのBですか? Bからの読み取りまたはへの書き込みはできませんfoo

4

3 に答える 3

8

あなたの場合、あなたconstは暗黙のうちに静的であるについて話している。静的メンバーは、とにかく事実上継承されません。仕様を確認したところ、静的メンバー継承されていることを意味しますが、静的メンバーは状態を表さず、ポリモーフィズムの一部にはできないため、少なくとも「異なる」種類の継承です。静的メンバーは、派生クラスがまったくアクセス可能であると仮定すると、派生クラスに対して単に「単純な名前で利用可能」であると考えています。つまり、実際の継承よりも名前解決に関係しています。

これがプライベートインスタンス変数である場合、それはから派生した任意のタイプのインスタンスの任意のインスタンスの状態の一部になるためA、継承された状態になります。オブジェクトの状態と動作が継承されることを考えると、それは私の見解では理にかなっています。

(静的部分とプライベート部分のどちらに関心があるかを明確にすることはおそらく価値があります。それらはある程度直交しています。)

于 2013-01-28T14:39:41.323 に答える
6

この記事はあなたを助けるかもしれません。

http://ericlippert.com/2011/09/19/inheritance-and-representation/

アクセスできないメンバーが継承されたと見なされるのはなぜですか?なぜそのような区別がなされた/実用的なのですか?

反対の質問をする方がよいでしょう。アクセスできないメンバーは継承されないというルールを作成することが実際的であるのはなぜですか。そのようなルールの結果を考えてみましょう。

まず、もしあなたが持っているなら

class B
{
  internal int x; 
}
class D1 : B {}
// in another assembly
class D2 : B {}

xはD1に継承されますが、D2には継承されないと言いますか?それは奇妙に思えます。または、この場合はどうですか?

class B
{
  private int x;
  private class D1 : B {}
}
class D2 : B {}

繰り返しますが、xはD1に継承されますが、D2には継承されないと言いますか?

いずれの場合も、派生クラスには整数フィールドxがありますが、一部のソースコードの場所でフィールドに名前でアクセスできないという理由だけで、その事実を否定しますか?「アクセス可能」の定義に非常に関連している「継承」の定義を作成する際の説得力のある価値は何ですか?

2つの概念を単純に直交させる方がはるかに簡単です。「継承」とは、「基本型のこのメンバーは派生型のメンバーでもある」という意味です。アクセシビリティは、アクセスするソースコードが宣言されたメンバーのアクセシビリティドメイン内にあるかどうかの問題です。それらは互いにほとんど関係がないので、不必要にそれらを混同しないようにしましょう。

于 2013-01-28T16:59:32.803 に答える
2

これは、デモンストレーションを通じて最も簡単に説明されます。

public class Parent
{
    private int value;
    public virtual int GetValue()
    {
        return value;
    }
}

public class Child : Parent
{
    public int GetOtherValue()
    {
        //"value" is no accessible in this scope
        return GetValue() + 1;
    }
}

オブジェクトが作成されると、そのタイプのすべてのインスタンスフィールドにメモリが割り当てられます。 Child実際には、0ではなく1つのインスタンスフィールド があります。はvalueから継承されParent、のインスタンスフィールドですChild。インスタンスを作成すると、Child独自の値がになりvalueます。ただし、そのvalueフィールドは定義でアクセスできませんChild(プライベートであるため)。Parentアクセス可能なメソッド/プロパティを介してのみアクセスできます

于 2013-01-28T15:12:36.423 に答える