クラス (インスタンスではなく) を見ると、次のように絵を描くことになります。

つまり、Dogクラスには通常、クラスよりも多くのメソッドとプロパティがありAnimalます (たとえば、犬にはbark(メソッド) があり、4 つのlegs(プロパティ) があります)。そしてもちろん、このクラスをインスタンス化するときに、追加のメモリを予約する必要があります。基本クラスのメソッドとプロパティが最初に作成され、次に派生メソッドとプロパティがメモリ内に作成されると想像してください。
class Dog : Animal
{
public Dog()
{
legs = 4;
Console.WriteLine("Dog constructor");
}
public int legs { get; private set; }
public void bark()
{
Console.WriteLine("grrrwoof!");
}
}
をインスタンス化し、それを参照変数Dogに割り当てた場合、この参照はが持つメソッドにのみアクセスできます。この事実にもかかわらず、オブジェクト全体はまだメモリに保持されています。AnimalAnimalDog
Dog d = new Dog();
Animal a = (Animal)d;
つまり、d次のことができます。
Console.WriteLine(String.Format("Number of legs: {0}", d.legs.ToString()));
d.bark();
これらの「機能」はクラスa内で定義されていないため、それはできません。Animal
ここで知っておくべき重要なことは、すべての種類のキャストが許可されているわけではないということです。これは安全であるため、常に aDogから anにキャストできますが、 anを a に暗黙的にAnimalキャストすることはできないため、次のコードは無効なキャスト例外をスローします。AnimalDog
Dog dogRef2 = a; // not allowed
何をしているのかわかっている場合 (つまり、aに のインスタンスが含まれていることが確実にわかっている場合Dog)、次のように明示的にキャストできます。
Dog dogRef2 = (Dog)a; // allowed
その後、プロパティとメソッドにアクセスできます。
dogRef2.bark(); // works
これが機能するのは、コンパイラとランタイムが常に同じ構造化された方法でメソッドとプロパティをメモリに格納し、参照時にそれを見つけるための内部記述子も作成するためです。
たとえば、次のことを試した場合、これは常に安全であるとは限らないことに注意してください。
Animal a = new Animal();
Dog dogRef2 = (Dog)a; // Invalid cast exception
なんで?new Animal()methodbarkと property を作成していないため、 ( propertyも method も含まない)legsのインスタンスを作成しただけです。Animallegsbark
詳細情報:内部構造 (オブジェクトの作成方法と保存方法) について詳しく知りたい場合は、このリンクを確認してください。そこから取ったメモリレイアウトの例を次に示します。

リンクされたリストを使用して、基本クラスのインスタンス オブジェクトから派生クラスのインスタンス オブジェクトへのチェーンを構築していることがわかります。