new
とvirtual
/には違いがありoverride
ます。
クラスは、インスタンス化されると、メソッドの実際の実装を指すポインタのテーブルに過ぎないと想像できます。次の画像はこれをかなりよく視覚化するはずです:
これでさまざまな方法があり、メソッドを定義できます。継承とともに使用すると、それぞれの動作が異なります。標準的な方法は常に、上の画像が示すように機能します。この動作を変更したい場合は、メソッドに別のキーワードを付けることができます。
1.抽象クラス
最初はabstract
です。abstract
メソッドは単にどこも指さない:
クラスに抽象メンバーが含まれている場合は、それもとしてマークする必要がありabstract
ます。そうでない場合、コンパイラーはアプリケーションをコンパイルしません。abstract
クラスのインスタンスを作成することはできませんが、クラスから継承して継承クラスのインスタンスを作成し、基本クラス定義を使用してそれらにアクセスすることができます。あなたの例ではこれは次のようになります:
public abstract class Person
{
public abstract void ShowInfo();
}
public class Teacher : Person
{
public override void ShowInfo()
{
Console.WriteLine("I am a teacher!");
}
}
public class Student : Person
{
public override void ShowInfo()
{
Console.WriteLine("I am a student!");
}
}
呼び出された場合、の動作はShowInfo
実装に基づいて異なります。
Person person = new Teacher();
person.ShowInfo(); // Shows 'I am a teacher!'
person = new Student();
person.ShowInfo(); // Shows 'I am a student!'
Student
sとTeacher
sはどちらもsですがPerson
、自分自身についての情報を要求するように求められたときの動作は異なります。ただし、情報の入力を求める方法は同じですPerson
。クラスインターフェイスを使用します。
だから、あなたが継承すると、舞台裏で何が起こりますPerson
か?を実装するShowInfo
と、ポインタはもはやどこも指さなくなり、実際の実装を指すようになります。Student
インスタンスを作成するとき、それはStudent
sを指しますShowInfo
:
2.仮想メソッド
2番目の方法は、virtual
メソッドを使用することです。基本クラスにオプションのデフォルト実装を提供していることを除いて、動作は同じです。virtual
メンバーを持つクラスはインスタンス化できますが、継承されたクラスは異なる実装を提供できます。実際に機能するコードは次のとおりです。
public class Person
{
public virtual void ShowInfo()
{
Console.WriteLine("I am a person!");
}
}
public class Teacher : Person
{
public override void ShowInfo()
{
Console.WriteLine("I am a teacher!");
}
}
主な違いは、基本メンバーPerson.ShowInfo
がもはやどこも指していないことです。これも理由であり、インスタンスを作成できる理由ですPerson
(したがって、これをマークする必要はありabstract
ません)。
今のところ、これは最初の画像と異なっていないことに注意してください。これは、virtual
メソッドが「標準的な方法」の実装を指しているためです。を使用すると、に別の実装を提供できる(必須ではない)とvirtual
伝えることができます。上記で私がしたように、異なる実装を(を使用して)提供した場合、イメージはと同じように見えます。sのカスタム実装を提供しなかったと想像してください。Persons
ShowInfo
override
Teacher
abstract
Student
public class Student : Person
{
}
コードは次のように呼び出されます。
Person person = new Teacher();
person.ShowInfo(); // Shows 'I am a teacher!'
person = new Student();
person.ShowInfo(); // Shows 'I am a person!'
の画像Student
は次のようになります。
3.魔法の「新しい」キーワード、別名「シャドウイング」
new
これはもっとハックです。基本クラス/インターフェースのメソッドと同じ名前を持つ、一般化されたクラスのメソッドを提供できます。どちらも独自のカスタム実装を指しています。
実装は、指定したものと似ています。メソッドへのアクセス方法に応じて、動作は異なります。
Teacher teacher = new Teacher();
Person person = (Person)teacher;
teacher.ShowInfo(); // Prints 'I am a teacher!'
person.ShowInfo(); // Prints 'I am a person!'
この動作は必要な場合がありますが、あなたの場合は誤解を招く可能性があります。
これにより、理解しやすくなります。