2012-01-12 32 views
2

私はこのコードを持っていますが、私はそれを理解できません。基本クラスによって実装されたインターフェイスを介してクラスのメソッドを呼び出すC#

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication1 { 
    interface IStoreable { 
     void Read(); 
     void Write(); 
    } 
    class Person : IStoreable { 
     public virtual void Read() { Console.WriteLine("Person.Read()"); } 
     public void Write() { Console.WriteLine("Person.Write()"); } 
    } 
    class Student : Person { 
     public override void Read() { Console.WriteLine("Student.Read()"); } 
     public new void Write() { Console.WriteLine("Student.Write()"); } 
    } 
    class Demo { 
     static void Main(string[] args) { 
      Person s1 = new Student(); 
      IStoreable isStudent1 = s1 as IStoreable; 

      // 1 
      Console.WriteLine("// 1"); 
      isStudent1.Read(); 
      isStudent1.Write();   

      Student s2 = new Student(); 
      IStoreable isStudent2 = s2 as IStoreable; 

      // 2 
      Console.WriteLine("// 2"); 
      isStudent2.Read(); 
      isStudent2.Write(); 

      Console.ReadKey(); 
     } 
    }  
} 

私はStudent.Write()は両方のケースで呼ばれることだろうと思ったので、私は私が得たもので困惑した

// 1 
Student.Read() 
Person.Write() 
// 2 
Student.Read() 
Person.Write() 

はなぜPerson.Write()ではなく、「Student.Write() `と呼ばれているのですか?

+2

オーバーライドとシャドーイングは異なるものです。 http://stackoverflow.com/questions/392721/difference-between-shadowing-and-overriding-in-c – Oded

答えて

4

を経由して「改質剤として使用する場合、新しいキーワードが明示的に基本クラスから継承されたメンバーを隠します」とにかく、PersonWrite()メソッドはvirtualとマークされていないので、できません。 IStoreableで呼び出すので、StudentクラスにリンクするIStoreableインターフェイスについては何もありません。 Write()にはvirtualと表示されていないので、この機能の多型は適用されません。

+0

私は 'Write()'をインタフェース型の参照を使って呼び出すと、実行されるメソッドもともとインターフェースを実装したクラス(この場合は 'Person')で実装されているものですか? – Robotron

+1

はい、基本クラスが 'Write()'メソッド 'virtual'をマークしなかったためです。したがって、そのサブクラスはそれを「オーバーライド」できません。 – FMM

+0

'IStoreable'にリンクされている唯一のものは基本クラス' Person'であり、(IStoreableを使って呼び出すときに)呼び出すメソッドに関するすべての結論がその事実から引き出されていますか? (実際に同じことを聞いて申し訳ありませんが、私が正しく理解していることを確認したい) – Robotron

0

人の書き込み方法を仮想にします。 newとマークすると、継承されたメソッドとして動作しません。メソッドのバーチャルにマークすると、実装を提供し、子クラスでオーバーライドできます。抽象メソッドを実装する必要があります(ほんの少しだけ)。

class Person : IStoreable { 
    public virtual void Read() { Console.WriteLine("Person.Read()"); } 
    public virtual void Write() { Console.WriteLine("Person.Write()"); } 
} 
class Student : Person { 
    public override void Read() { Console.WriteLine("Student.Read()"); } 
    public override void Write() { Console.WriteLine("Student.Write()"); } 

newキーワードは、あなたが(基本クラスのWrite()メソッドをオーバーライドすることができつもりがないことを示し

0

IStoreableとしてのStudentは、基本クラスPersonからオーバーライドされていないため、Student.Writeメソッドを表示できません。なぜそれは仮想マークされていないのですか?また、基本クラスの実装を隠すために新しいキーワードを使用した理由は何ですか?

+0

これは、地方大学の教科書の単なる例です。それは私に貸し出されたので、私はこの例を見つけ出し、それを理解できませんでした。 – Robotron

+0

ああ、それは良い質問です。あなたの質問に対するOdedのコメントも参考になります。 – Jeb

関連する問題