今天,在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();
}
}
这是我的问题:
答案 0 :(得分:9)
1:您重新声明方法(new
);如果你override
它应该工作。 new
打破了任何多态行为。
2:您正在重新实施界面;这确实称为最高的实施。同样,override
会解决这个问题。
class Flugzeug : ILuftfahrzeug {
public virtual void Starten() {
Console.WriteLine("Das Flugzeug startet, " + Dings());
}
protected virtual string Dings() {
return "Flugzeug Dings";
}
}
class Motorflugzeug : Flugzeug {
public override void Starten() {
Console.WriteLine("Das Motorflugzeug startet, " + Dings());
}
protected override string Dings() {
return "Motorflugzeug Dings";
}
}
答案 1 :(得分:1)
只需确保声明您希望能够覆盖为虚拟的方法。然后在继承的类上使用override关键字。
更新1:新关键字明确指出,在直接使用该类时,仅在继承类上声明非虚方法只会隐藏基本方法。无论何时使用基类,都无需隐藏。
答案 2 :(得分:0)
新的keywork和override关键字执行两个非常不同的事情,并且您正在体验new的行为,从您的描述中我认为您希望使用覆盖,因为这遵循通常预期的继承行为。您需要在基类中声明方法/属性virtual并使用override而不是new。
是的,太慢了!答案 3 :(得分:0)
这是因为您使用“新”修饰符,请参阅MSDN
您应该使用“覆盖”而不是
答案 4 :(得分:0)
已实现的接口成员不是自动虚拟的。由你来决定虚拟,抽象等等。
答案 5 :(得分:0)
您的计划没有按预期执行的原因是因为您的方法中使用new
关键字。
c#方法不是动态绑定的。这意味着调用的方法在编译时确定。您可以查看变量的类型确定调用哪个方法而不是内存中的实际对象。
要获得所需的效果,您需要确保c3动态绑定方法。你可以通过声明方法virtual
和重写方法override
来做事。
class Flugzeug : ILuftfahrzeug
{
public virtual void Starten()
{
Console.WriteLine("Das Flugzeug startet, "+Dings());
}
protected virtual string Dings()
{
return "Flugzeug Dings";
}
}
class Motorflugzeug : Flugzeug, ILuftfahrzeug
{
public override void Starten()
{
Console.WriteLine("Das Motorflugzeug startet, "+Dings());
}
protected override string Dings()
{
return "Motorflugzeug Dings";
}
}
通常,永远不要在方法上使用new
。它几乎永远不会做你想要的。
答案 6 :(得分:0)
我的第二个弗雷迪里奥斯关于虚拟关键字的观点。除非你的基类使用virtual关键字声明一个方法,否则根本就没有多态行为。无论您使用覆盖还是新的。