2009-03-30 11 views
3

私は問題を抱えている...ここで、「ToStringメソッドは、」正しいメソッドを呼び出していないC#のToStringメソッドの継承

public class ClassA 
{ 
    public override ToString() 
    { 
     return "Hello, I'm class A."; 
    } 
} 

public class ClassB : ClassA 
{ 
    public override ToString() 
    { 
     return "Hello, I'm class B."; 
    } 
} 

ClassB myClassB = new ClassB(); 
List<ClassA> myClassAList = new List<ClassA>(); 

myClassAList.Add((ClassA) myClassB); 
ClassA tempClassA = myClassAList[0]; 
Console.WriteLine(tempClassA.ToString()); 

Iを(それが、私はちょうど私が間違ってやって見つけることができない私のせいです)私が間違っているのは "ClassA"ではなく "ClassB"から "ToString"を取得していますか?

+0

複数のタイプミス: "pulbic"、 "retutn"、 "pulbic" – abelenky

答えて

4

ToStringをClassBでオーバーライドしていますが、オーバーライドされたメソッドが優先されるように元のクラスから隠すのではなく、ClassBでオーバーライドしています。あなたができることは..

public class ClassA 
{ 
    public override string ToString() 
    { 
     return "Hello, I'm class A."; 
    } 
} 

public class ClassB : ClassA 
{ 
    public new string ToString() 
    { 
     return "Hello, I'm class B."; 
    } 
} 

... 

List<ClassA> theList = new List<ClassA> 
{ 
    (ClassA)new ClassB(), 
    (ClassA)new ClassB() 
}; 

ClassA a = theList[0]; 
Console.WriteLine(a.ToString()); 

// OR... 

Console.WriteLine(new ClassA().ToString()); // I'm Class A 
Console.WriteLine(new ClassB().ToString()); // I'm Class B 
Console.WriteLine(((ClassA)new ClassB()).ToString()); // I'm Class A 
+0

これは何も変わりません。ここでClassAのインタフェース契約を破棄することはできません。 –

+1

ToStringメソッドを新規で隠し、ClassBをClassAにダウンキャストしてToString()を呼び出すと、ClassAのオーバーライドされたToStringメソッドが取得されます。それを試してみてください。Console.WriteLine(((ClassA)new ClassB())。ToString()); –

+0

私は試しました。あなたは間違っている。 –

0

ToStringは仮想メソッドですが、変数の型が何であっても問題ではありません。実際のオブジェクトの型は何であるかは重要です。

メソッドが仮想でない場合は、コンパイラが知っているメソッドClassA ToStringメソッドが呼び出されます。

仮想メソッドは、オブジェクトタイプにバインドされたルックアップテーブルによって実装されます。変数 "tempClassA"で終わるオブジェクトは実際にはClassB型のオブジェクトであるため、ClassBのルックアップテーブルが使用されるため、そのクラスのToStringメソッドが使用されます。

6

あなたは何も間違っているわけではありません。これが多態性仮想メソッドの仕組みです。 ClassBをClassA参照のコレクションに入れると、それはまだClassBオブジェクトです。オブジェクトが実際にClassBである場合、.ToString()を呼び出すと常にClassB.ToString()が検索されます。

0

あなたは正しい結果を得ています。 ClassBのインスタンスをリストに追加します。たとえそれをClassAとして扱っても。したがって、仮想ToStringメソッドを呼び出すと、ClassBのToStringが呼び出されます。これは実際に作業しているオブジェクトの種類なので、