2012-02-16 13 views
0

すべてのクラスはsystem.objectから派生しているため、派生クラスオブジェクトは階層内のクラスを参照していますか?例えば新しく作成された特定のクラスのオブジェクトは、それが派生したクラスをどのように参照していますか?

public class A 
{ 
//contains some attributes and methods 
} 

public class B: A 
{ 
//contains some attributes and methods 
} 

public class C: B 
{ 
//contains some attributes and methods 
} 

のため(だけの当然それらの上のクラス)

は今CLASS "C" のOBJECT A、BなどのSystem.Objectクラスを参照していますか?

+1

「参照先」とはどういう意味ですか?クラスCのオブジェクトは、クラスAからだけでなく、クラスBからも継承されます。 – Blorgbeard

+0

クラスcのオブジェクトが作成されたときを参照してください。最初にクラスsystem.objectのオブジェクトが作成され(最高レベルの基本クラスとして)、そのオブジェクトへの参照がSOMEWHEREに送信されなければなりません(このrefrenceはどこにありますか?)、クラスAのオブジェクトが作成され、それへのrefrecneはどこかどこに送信しなければならない、次に階層Bのオブジェクトは、このオブジェクトのアドレスを作成しなければなりません最終的に送信されなければならないCクラスのオブジェクトが作成され、ここで私の質問は、 (Cが派生したすべてのクラスの参照) –

+1

いいえ..インスタンスが1つしかなく、クラスCです。このオブジェクトは「C」です - したがって、B、A、およびシステムです.Object - それはCであることが意味するものの一部です。 – Blorgbeard

答えて

0

タイプCのオブジェクトも、タイプB、A、およびSystem.Objectです。

継承元の他のクラスのすべてのメンバー(publicまたはprotectedメソッド、プロパティ、およびフィールド)を持ちます。これは、すべてのオブジェクトに "ToString"メソッドがある理由です。System.Objectから継承しています。

+0

ですが、その派生オブジェクトはこれらのクラスb、aおよびsystem.objectを参照していますか? ...私はCクラスのオブジェクトは、メモリ内のこれらのクラスすべてへの参照を含んでいますか? .. –

+0

@SanaZehra:あなたが「参照する」ことによって何を意味するのかは完全には不明であるので、人々はあなたの質問によって混乱していると思います。あなたがお米のボウルを持っているとします。さて、私はあなたに "あなたのお皿はコンテナを参照していますか?そして、お米は食べ物を参照していますか?"あなたはその質問を明確にするために私に尋ねることで完全に正当化されるでしょう。 「ホワイトハウスという言葉は、ワシントンDCの1600ペンシルバニア・アベニューと同じ家を指していますか?それははるかに明確な質問です。「参照してください」とは何の意味も明確ではありません。 –

+1

それは4つの別々のオブジェクトとしてメモリに格納されていないので、1つのオブジェクトとして保存されます(定義は4つのオブジェクトすべてのメンバーのコンボです)。私は「ゴールデンレトリバー」と言いますと、私は動物を指しているわけではありません。動物の特定のタイプを指しています。 – Arbiter

0

はい。すべてのクラスは、デフォルトで暗黙的にsystem.objectクラスを参照します。

+0

ですが、その派生オブジェクトはこれらのクラスb、aおよびsystem.objectを参照していますか? ...私はCクラスのオブジェクトは、メモリ内のこれらのクラスすべてへの参照を含んでいますか? .. –

0

正確ではありませんが、他のどのセマンティクスよりも意味があります。クラスCの

オブジェクトしかし、それはタイプA、B又は単に昔ながらのSystem.Objectのオブジェクトにキャスト型であってもよいC.という名前のクラス定義のインスタンスを指します。

CとA/B/System.Objectの間には「参照」はありません。これらのクラス定義のすべてを統一された "C"に統合することは、より重要です。これが何を意味するのか

は、あなたが次の操作を行うことができるということです。上記の場合

function void DoSomething(A input) { 
    // do something as A 
} 

C myObj = new C(); 

DoSomething(myObj); 

を、CはdoSomethingの呼び出しのタイプAのオブジェクトに型キャストになります。

また、のようなものを行うことができます。

public class A { 
    public String MyValue { get; set; } 
} 

public class B : A{ 
    public String AnotherValue { get; set; } 
} 

public class C : B { 
    public void DoSomething() { 
    MyValue = "Hello"; 
    AnotherValue = "World"; 
    } 

    public String Output() { 
    return String.Format("{0} {1}", MyValue, AnotherValue); 

    } 
} 

C myObj = new C(); 
C.DoSomething(); 
String message = C.Output(); 
// value of message will be "Hello World" 

今すぐ逆が真ではありません。あなたは、次の操作を行うことはできません。この場合

function void DoSomething(C input) { 
    // do something as C 
} 

A myObj = new A(); 

DoSomething(myObj); 

あなたはコンパイラエラーを持っているでしょう。

1

コメントを読めば、クラスCのインスタンスを作成するときに、クラスB、A、またはオブジェクトのインスタンスが別々に存在すると誤解されるようです。そうではありません。クラスCのインスタンスである単一のオブジェクトがあり、クラスB、A、またはオブジェクトのインスタンスとして扱うこともできます(Liskov Substitution Principleで読んでください)。 Eric Lippertの類推を変えるには:犬が生まれたとき(生まれて)、それは犬、哺乳動物、動物です。しかし、唯一の犬があります。

検討この(動物、哺乳類、犬、代わりのA、B、C):

public class Animal 
{ 
    void Breathe(); 
} 

public class Mammal : Animal 
{ 
    void GrowHair(); 
} 

public class Dog 
{ 
    void Bark(); 
} 

この継承チェーンは以下の効果が得られる:、フィールドの観点から

public class C 
{ 
    void Breathe(); 
    void GrowHair(); 
    void Bark(); 
} 

および

public class A    
{    
    private int _a; 
}    

public class B: A    
{    
    private int _b; 
}    

public class C: B    
{    
    private int _c; 
} 

Aのインスタンスはどのようにメモリ内を見ますか?A、B、Cに戻る_aのためのオーバーヘッドのバイトに加え、4バイトのいくつかの数:

OVERHEAD 
_a : four bytes 

どのようにして、メモリ内のBの外観のインスタンス?それはちょうどAプラス4バイト以上のインスタンスのようになります。

OVERHEAD 
_a : four bytes 
_b : four bytes 

そして、Cのインスタンスは、Aプラス8バイト以上のインスタンスのようになります。

OVERHEAD 
_a : four bytes 
_b : four bytes 
_c : four bytes 

そのオーバーヘッドは何ですか?当然、は、Objectクラスで定義されたものです!したがって、継承チェーンに別のクラスを追加するたびに、そのクラスで定義されたフィールドは、親クラスのメモリ構造の最後に追加されます。

派生クラスのインスタンスがでない場合は、親クラスによって定義されたデータをと参照してください。 には、親クラスによって定義されたデータがに含まれています。

+0

ありがとうございました! =)thatsは私が知りたいと思ったものです。また、私は "C"のオブジェクトを作成するときに呼び出されるSYSTEM.OBJECT **だけでなく、A、B **のデフォルトのコンストラクタは、クラス "C"で任意の既定(ゼロパラメーター化)コンストラクタを言及しない? - –

+0

@SanaZehraはい;他の基本クラスのコンストラクタを特に呼び出さない場合は、基本クラスのデフォルトのコンストラクタが呼び出されます。 – phoog

+0

ありがとうございます。=) –

6

私はしばらく時間がかかりましたが、わかりました。 C#は "プロトタイプ継承"言語だと思います。そうではない。

JavaScriptのようなプロトタイプ継承言語では、すべてのオブジェクトに「プロトタイプオブジェクト」の参照があります。だから、JavaScriptで、あなたは言うかもしれない:

function Dog() {} 
Dog.prototype.legs = 4; 
var rover = new Dog(); 
var spot = new Dog(); 
spot.legs = 3; // Poor spot! 
print(rover.legs); // 4 
print(spot.legs); // 3 

roverspot両方が参照Dog.prototypeからを持っています。 rover "あなたは何脚ありますか?" roverは「わからない、私のプロトタイプを聞かせてください」と言っています。 roverによって参照されるオブジェクトは、Dog.prototypeによって参照されるオブジェクトへの参照を持ち、そのオブジェクトはlegsプロパティを持ちます。

あなたがspotを頼む「あなたはどのように多くの足を持っているのですか?」、spotもそのプロトタイプへの参照を持っていますが、spotはすでにそれが持っているどのように多くの足を知っているので、それは、それを必要としません。

もう少し作業すれば、プロトタイプDog.prototypeが "Animalプロトタイプオブジェクト"であるシステムを構築することができました。そして、チェーンは続くでしょう。 roverDog.prototypeへの参照を有し、Dog.prototypeAnimal.prototypeへの参照を有し、Animal.prototypeObject.prototypeへの参照を有する。

C#はまったく同じように動作しません。 JavaScriptでは、オブジェクトはプロトタイプのリンクリストの一部であり、プロトタイプチェーンはプロパティを参照する必要があるときに検索されます。 C#では、各プロパティのすべての情報は、すべてのインスタンスでに格納されます。 C#では、オブジェクトはその基本型のインスタンスを参照せず、基本型のインスタンスを含みません。むしろのすべての基本型のメンバーを継承します。 (コンストラクタとデストラクタ以外)

+0

ありがとうございました。 ur explainationsは私の質問に対する答えを見つけるのを助けました! –

+0

@ErricLipert まだコンストラクタは継承されていますか? ..私は派生クラスでは、ゼロのパラメータ化されたコンストラクタを提供していない場合...ベースクラスのコンストラクタが呼び出されます。 –

+0

@SanaZehra:コンストラクタは継承されません。コンストラクタの提供に失敗した場合は、基本クラスのコンストラクタがある場合はそれを*コールするコンストラクタを無料で取得します。 *基本クラスのコンストラクタを継承しません。あなたは*それを呼び出す。 –

関連する問題