C#虚関数


インスタンスメソッドが宣言される前にvirtualキーワードが付いている場合、このメソッドは虚メソッドです.虚法と非虚法の最大の違いは,虚法の実現が派生クラスに取って代わることができることである.この置換は方法の書き換えによって実現される.(後述)虚メソッドの特徴:虚メソッドの前にstatic,abstract,またはoverride修飾子虚メソッドはプライベートではないためprivate修飾子虚メソッドの実行は許されない:一般関数はコンパイル時に実行ファイルに静的にコンパイルされ、その相対アドレスはプログラム実行中に変化せず、虚関数はコンパイル中に期間は静的にコンパイルされず、その相対アドレスは不確定であり、実行時期オブジェクトインスタンスに基づいて呼び出す関数を動的に判断し、その申明時に定義されたクラスを申明クラスと呼び、その実行時にインスタンス化されたクラスをインスタンスクラスと呼ぶ.A a=new B();このうちAは申明類,Bは実例類である.1.オブジェクトの関数を呼び出すと、システムは直接このオブジェクトが定義したクラス、すなわち、呼び出された関数が虚関数であるかどうかを確認します.2.虚関数でない場合は、その関数を直接実行します.虚関数の場合、この時点ではすぐに関数を実行するのではなく、オブジェクトのインスタンスクラスのチェックを開始します.3.このインスタンスクラスでは、彼はこのインスタンスクラスの定義に虚関数が実装されているかどうか、または虚関数が再実装されているかどうかを確認します.(overrideキーワードによる)メソッドは、ある場合は検索せず、そのインスタンスクラスで実装された虚関数のメソッドをすぐに実行します.ない場合は、インスタンスクラスの親を探し続け、最初に虚関数を再ロードした親を見つけるまで、親クラスについて先ほどのチェックを繰り返します.に表示されます.例1:
    class A
{
public virtual void Sum()
{
Console.WriteLine(
"I am A Class,I am virtual sum().");
}
}
class Program
{
static void Main(string[] args)
{
A a
=new A(); //  a A . A a , a ,A a  
a.Sum();
Console.Read();
}
}

a.Sum:1を実行します.まず申明類A 2を検査する.sumが仮想メソッドであることが確認された.インスタンスクラスAをチェックすると、問題そのものが4になる.インスタンスクラスAでSumを実現する方法5を実行する.結果I am A Class,I am virtual sum()を出力.例2:
class A
{
public virtual void Sum()
{
Console.WriteLine(
"I am A Class,I am virtual sum().");
}
}
class B : A
{
public override void Sum() //
{
Console.WriteLine(
"I am B Class,I am override sum().");
}

}
class Program
{
static void Main(string[] args)
{
A a
=new B(); //  a A . A a , a ,B a  
a.Sum();
Console.Read();
}
}

a.Sum:1を実行します.まず申明類A 2を検査する.仮想メソッド3であることが確認された.インスタンスクラスBをチェックして書き換える方法がある.インスタンスクラスBのメソッド5を実行する.結果I am B Class,I am override sum()を出力.例3:
    class A
{
public virtual void Sum()
{
Console.WriteLine(
"I am A Class,I am virtual sum().");
}
}
class B : A
{
public override void Sum() //
{
Console.WriteLine(
"I am B Class,I am override sum().");
}

}
class C : B
{

}
class Program
{
static void Main(string[] args)
{
A a
=new C();//  a A . A a , a ,C a  
a.Sum();
Console.Read();
}
}

a.Sum:1を実行します.まず申明類A 2を検査する.仮想メソッド3であることが確認された.インスタンスクラスCをチェックし、書き換えの方法4がない.クラスCの親クラスBをチェックして、書き換える方法があります.親BのSumメソッド6を実行する.結果I am B Class,I am override sum()を出力.例4:
   class A
{
public virtual void Sum()
{
Console.WriteLine(
"I am A Class,I am virtual sum().");
}
}
class B : A
{
public new void Sum() //
{
Console.WriteLine(
"I am B Class,I am new sum().");
}

}
class Program
{
static void Main(string[] args)
{
A a
=new B();
a.Sum();
Console.Read();
}
}

a.Sum:1を実行します.まず申明類A 2を検査する.仮想メソッド3であることが確認された.インスタンスクラスBをチェックして、書き換えがない(ここで注意したいのは、Bに実装Sum()があるが、overrideキーワードを使用していないので書き換えとは思われない).検査クラスBの親Aを回すと、それ自体が5.親AのSumメソッド6を実行する.結果I am A Class,I am virtual sum()を出力.では、例4では、クラスBを明記しているのでしょうか.
    class A
{
public virtual void Sum()
{
Console.WriteLine(
"I am A Class,I am virtual sum().");
}
}
class B : A
{
public new void Sum() //
{
Console.WriteLine(
"I am B Class,I am new sum().");
}

}
class Program
{
static void Main(string[] args)
{
B b
=new B();
b.Sum();
Console.Read();
}
}

BクラスのSum()を実行し、結果I am B Class,I am new sum()を出力する.抽象関数を使用してベースクラスの虚関数を書き換えることができますか?答えはいいです.
    class A
{
public virtual void PrintFriends()
{
Console.WriteLine(
"A.PrintFriends()");
}
}
abstract class B : A
{
public abstract override void PrintFriends();
// override ,
}
abstract class C : A
{
public abstract new void PrintFriends(); //
new ,
}

シール類には虚関数がありますか?はい、ベースクラスの虚関数は暗黙的な非虚関数に変換されますが、シールクラス自体は新しい虚関数を追加することはできません.
    class A
{
public virtual void Fun()
{
Console.WriteLine(
"I am A.");
}
}
sealed class Program:A
{
public override void Fun()
{
Console.WriteLine("I am B."
);
}
static void Main(string[] args)
{
Program p
= new Program();
p.Fun();
Console.Read();
}
}