【发布时间】:2009-03-03 19:48:18
【问题描述】:
今天,在用 c# 实现一些测试类时,我偶然发现了一些关于 c# 中继承(和接口)的问题。下面我有一些示例代码来说明我的问题。
interface ILuftfahrzeug
{
void Starten();
}
class Flugzeug : ILuftfahrzeug
{
public void Starten()
{
Console.WriteLine("Das Flugzeug startet, "+Dings());
}
protected string Dings()
{
return "Flugzeug Dings";
}
}
class Motorflugzeug : Flugzeug, ILuftfahrzeug
{
public new void Starten()
{
Console.WriteLine("Das Motorflugzeug startet, "+Dings());
}
protected new string Dings()
{
return "Motorflugzeug Dings";
}
}
class InterfaceUndVererbung
{
static void Main(string[] args)
{
//Motorflugzeug flg = new Motorflugzeug(); // case1: returns "Das Motorflugzeug startet, Motorflugzeug Dings"
//Flugzeug flg = new Motorflugzeug(); // case2: returns "Das Flugzeug startet, Flugzeug Dings"
ILuftfahrzeug flg = new Motorflugzeug(); // case3: returns "Das Motorflugzeug startet, Motorflugzeug Dings"
// if Motorflugzeug implements ILuftfahrzeug explicitly,
// otherwise "Das Motorflugzeug startet, Motorflugzeug Dings"
flg.Starten();
Console.ReadLine();
}
}
这些是我的问题:
- 使用 Flugzeug 声明和初始化 flg = new Motorflugzeug(); (case2)我希望调用 Motorflugzeug.Starten 而不是 Flugzeug.Starten(我很确定这是 Java 显示的行为)。 openbook.galileo 说在这种情况下使用 c# 运行时类型是 Flugzeug。有什么理由吗?对我来说,这种继承行为毫无意义。
- 与 ILuftfahrzeug flg = new Motorflugzeug() 相同; (case3) - 在这里我可以通过让 Motorflugzeug 显式地实现 ILuftfahrzeug 来解决问题(就像在示例代码中一样)。但对我来说这是多余的,因为 Flugzeug 已经实现了 ILuftfahrzeug。
- 现在我想覆盖由 Starten() 调用的受保护方法 Dings()。如果我按照示例中的实现方式运行代码,则一切正常。但是如果在 Motorflugzeug 中没有实现 Starten(),则将调用基类的 Dings() 而不是 Motorflugzeug.Dings()。有人告诉我,Java 也表现出这种行为。
有什么模式可以解决这个问题吗?否则,我将不得不覆盖调用我实际打算覆盖的方法(此处:Dings())的每个方法(此处:Starten()),即使它与基类中的完全相同。
【问题讨论】:
标签: c# inheritance interface