通过基类c#实现的接口调用类的方法

时间:2012-01-12 20:26:31

标签: c# interface derived-class base-class

我有这段代码,但我无法理解。

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()`?

3 个答案:

答案 0 :(得分:4)

new关键字表示您不打算覆盖基类的Write()方法(您无论如何都不能,因为Person的{​​{1}}方法不是'标记为Write())。由于您是通过virtual调用它,因此IStoreable接口将其链接到IStoreable类没有任何内容。由于Student未标记Write(),因此此函数的多态性不适用。

答案 1 :(得分:0)

将此人的写入方法设为虚拟。标记为new时,它不会作为继承方法。当您将方法标记为虚拟时,这意味着您提供了一个实现,并且可以通过子类覆盖它。摘要要求你实现一个方法(只是多一点fyi)。

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关键字显式隐藏从基类继承的成员”通过

答案 2 :(得分:0)

作为IStoreable的学生无法看到Student.Write方法,因为它没有从基类Person重写。为什么它没有标记为虚拟,为什么你使用new关键字来隐藏基类的实现?