2016-06-14 4 views
-2

私は以下のように、基本クラス過ごしていた場合:リアルタイムでC#の仮想メソッドと新しいメソッドをオーバーライドする方法は何ですか?

class A 
{ 
    public virtual void print() 
    { 
     Console.WriteLine("Base class method"); 
     Console.Read(); 
    } 

} 

を、以下のような基本クラスから継承した派生クラス:オブジェクトを作成するために

class B : A 
{ 
    public override void print() 
    { 
     Console.WriteLine("Child Class Method"); 
     Console.Read(); 
    } 
} 

主な方法は以下の通りです:

class Method 
{ 
    static void Main(string[] args) 
    { 
     A obj=new B(); 
     obj.Print(); 
    } 
} 

上記のコードは、子クラスのメソッドを呼び出します。しかし、私がB obj=new B()のようなオブジェクトを作成し、 'obj.Print()'を行ったとしても、同じ出力がレンダリングされます。

したがって、上記のようなA obj=new B()と呼び出し方法のようなオブジェクトの作成は何ですか?私は以下のように派生クラスのメソッドを変更した場合

一方、:

public new void print() 
{ 
    Console.WriteLine("Child Class Method"); 
    Console.Read(); 
} 

そして、もしA obj=new B()は、その後、obj.print()は、基本クラスのメソッドを呼び出しますか。同じ場合はA obj=new A()obj.print()です。

だから、派生参照クラスオブジェクトを指し、上記のようなメンバーを呼び出す基本クラス参照変数を持つ点は何ですか?どのシナリオでこのロジックを使用すべきですか?

+0

'B'クラスのメソッド名は' PrintMaessage'ですか?明らかに、あなたが 'obj.Print()'を呼び出すと、それが呼び出されることはありません。 –

+0

1ワード:多型。 – Spivonious

+0

@ IanMcLaird - もちろんです。私は投稿を編集しました。 – Abhi

答えて

1

あなたはこのシグネチャを持つメソッドを持っている:https://stackoverflow.com/a/6162547/6460438

void Print(ICollection<A> objects) 
{ 
    foreach(var obj in objects) 
    { 
     obj.print(); 
    } 
} 

printは、(それがないnewprint方法を行い、別の子C可能性がありA用) 読書をB実装やA実装のいずれかを使用します

+0

この例は、 'var'の代わりに' A'を使用した場合には、ポイントになります。 –

+0

型はパラメータの型によって表現されるので、実際はありません。 – Greg

+0

@ Greg、ありがとうございます。提供されているリンクは非常に便利でした。 – Abhi

0

これを行う理由は、多型性のためです。

void Process(A item) 
{ 
    item.print(); 
} 

は今、あなたが言うことができる:

B b = new b(); 
Process(b); 

を、メソッドがAがかかりますが、それは正しい実装に派遣するたとえば、あなたが方法を持っているかもしれません。

0

ここ指導原理は、オブジェクトを扱っているとき、あなたはあなたのニーズを満たす最も広いタイプ(少なくとも由来のタイプ)を使用する必要があります、ということです。これは、「インプリメンテーションではなくインターフェイスへのコード」と表現されることがあります。しかし、その用語で混乱しないでください。基本クラスに対するコーディングも、あなたのニーズを満たす型であれば問題ありません。

理由は簡単です:後でメンテナンスとリファクタリングを簡素化し、コードを他の場所で再利用しやすくします。変数の型は、その変数がどのように機能するかを約束します。それらの約束を広げると、関数をより広く適用できるようになるのは簡単です。変数型の基本クラスを選択すると、後で基本となる実装を変更することがより確実になります。あなたの例では

、IコードAに対して、しかしBのインスタンスを作成する場合、私は私がしたい場合は、私は、この機能でそれを使用することができますclass C : A { ... }を追加するとき、私は、それ以降のかなり確信することができます。私がBに対して直接コードすると、それは証明するのが難しいです。これらのキーワードは、このどのように関係するかについては

virtualは(実際には、我々はおそらくサブクラスが、少なくとも時折、それを再定義することを期待)サブクラスは再定義することができるものであるとしてメソッドをマークするために使用されます。これは、ほとんどの場合有効な妥当なデフォルトの実装があるのに、サブクラスがその機能を潜在的に最適化して自分自身のために使用できるようにする場合に使用します。

abstractは、このクラスがサブクラスがいくつかの欠落した詳細を「埋める」ことを期待していることを示すために使用されます。メソッドの実装方法を知る方法がないときにこれを使用しますが、メソッドが必要であることはわかっています。 abstractの方法は常にvirtualです。 classabstractのメソッドが定義されている場合、そのクラス自体はabstractでなければならず、実際にそのインスタンスを作成することはできません。私の経験上、abstractvirtual以上に使用しています。

overrideは、このクラスは実際(再)親クラスの振る舞いを定義していることを示すために使用されます。

newはわずかに特殊です。親クラスはメソッドを再定義するためにそのサブクラスに明示的に許可を与えなければならないので、私たちはどこでも好きなだけoverrideすることはできません。これは通常です。のものですが、ルールの外に出なければならないこともあります。 (そのジャークライブラリの作者は、方法を作るのを忘れてしまいましたvirtualと私たちが実行する必要がある主要な最適化が...)それはnewのためです。彼らは途方もなく継承されなければならない。このは非常にを控えめに使用してください。

関連する問題