派生自实现接口的基类

时间:2011-08-17 14:22:56

标签: c#

我从Effective C#第23项获得以下代码应打印:MyDerivedMessage

namespace ConsoleApplication1
{

    interface IMsg
    {
        void message();
    }

    public class MyMessage : IMsg
    {
        public void message()
        {
            Console.WriteLine("MyMessage");
        }
    }

    public class MyDerivedMessage : MyMessage
    {
        public new void message()
        {
            Console.WriteLine("MyDerivedMessage");
        }
    }

    class Test
    {

        static void Main()
        {
            MyDerivedMessage mdm = new MyDerivedMessage();
            IMsg im = mdm as IMsg;
            im.message();
        }
    }
}

图书:

public class MyDerivedClass : MyClass
{
    public new void Message()
    {
        Console.WriteLine("MyDerivedClass");
    }
}

添加IMsg关键字会更改派生的行为     class,以便IMsg.Message()现在使用派生类版本:

MyDerivedClass d = new MyDerivedClass();
d.Message(); // prints "MyDerivedClass".
IMsg m = d as IMsg;
m.Message(); // prints " MyDerivedClass "

在向MyMessage添加“新”后,为什么还会打印MyDerivedMessage::message()

2 个答案:

答案 0 :(得分:3)

您隐藏(或隐藏)该方法而不是覆盖它。这意味着当您从声明为该类(或更多派生类)的变量访问它时,您将只调用派生类上的方法。

请注意,这是非虚拟方法的默认设置,因此添加“new”只是更明确。

如果您不想要这种行为,则需要在基类中创建message方法虚拟,并在派生类中覆盖它。

另见new Modifier

上的文档

答案 1 :(得分:1)

似乎这本书可能有一些勘误,但你的MyDerivedMessage类还需要实现IMsg。如果没有发生这种情况,那么当调用im.message()时,由于在Interface和MyDerivedMessage之间创建链,对IMsg的强制转换只会看到MyMessage具有Message()方法。

MyDerivedMessage是一个MyMessage MyMessage是一个IMsg MyDerivedMessage NOT是一个IMsg

public class MyDerivedMessage : MyMessage, IMsg
{ 
    public new void message() 
    { 
        Console.WriteLine("MyDerivedMessage"); 
    } 
}