C#接口,多态性和代理

时间:2012-06-24 12:02:42

标签: c# inheritance delegates polymorphism

当我结合接口和多态时,我搞得一团糟。

说我有以下界面:

public Interface CanSayHello
{
     String SayHello();
}

以下课程:

public Class Person : CanSayHello
{
     public String SayHello() { return "Hey, I'm a person just saying hello to you";}
}

最后是重要的班级:

public Class PoshPerson: Person
{
     public String SayHello() { return "Hey, I'm too posh to say hello to you";}
}

我的第一个问题是以下代码会收集PoshClass或Person Class的方法吗?

public delegate String Collector();
event Collector CollectorEvent;
void GetMethod(CanSayHello c){CollectorEvent += c.SayHello;}

**GetMethod(new PoshPerson());**

如果它将从Person类收集方法,我想我应该将Person的方法声明为virtual,并将PoshPerson的方法覆盖。 我真的希望这两个方法签名是相同的。有可能吗?

3 个答案:

答案 0 :(得分:4)

您的示例运行Person的方法。如果您将PoshPerson更改为PoshPerson : Person, CanSayHello(您可能认为自Person : CanSayHello以来不会改变任何内容),则会运行PoshPerson的方法。

我同意@millimoose:“我会尽可能地避免方法隐藏,正是因为编译时多态性不是很直观。”我建议您将Person.SayHello更改为virtual,将PoshPerson.SayHello更改为override。这样,无论您是将实例都知道为CanSayHelloPerson还是PoshPerson,当前实例类型的方法都会运行。

答案 1 :(得分:1)

您的示例将运行Person的版本。请参阅此处的说明:http://msdn.microsoft.com/en-us/library/aa664593(v=vs.71).aspx。如果在派生类中重新定义方法(编译后将PoshPerson.SayHello视为使用new来重新定义它),并且基类实现了接口,则重新定义的方法不会更改接口映射。

如果你让PoshPerson重新实现界面,它会调用PoshPerson的SayHello。

public class PoshPerson : Person, CanSayHello
{
    public String SayHello() { return "Hey, I'm too posh to say hello to you";}
}

或者如果你在Say中使SayHello虚拟,然后在PoshPerson中覆盖它,它将调用PoshPerson的SayHello。

答案 2 :(得分:1)

我认为你想要更多的东西:

public interface ITalkable
{ 
     string SayHello(); 
     string SayGoodbye();
     etc...
}

public class Person : ITalkable
{ 
     public virtual string SayHello() { return "Hey, I'm a person just saying hello to you";} 
     public virtual string SayGoodbye() { return "Hey, I'm a person just saying goodbye to you";}
} 

public class PoshPerson: Person 
{ 
     public override string SayHello() { return "Hey, I'm too posh to say hello to you";}
     public string MakePersonSayHello() { return base.SayHello(); } 

}