[英]Unexpected behaviour of inheritance and interfaces in c#
Today, while implementing some testclasses in c#, I stumpled on some questions regarding inheritance (and interfaces) in c#. 今天,在c#中实现一些测试类时,我在c#中讨论了有关继承(和接口)的一些问题。 Below I have some example code to illustrate my questions.
下面我有一些示例代码来说明我的问题。
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();
}
}
These are my questions: 这些是我的问题:
1: you are re-declaring the method ( new
); 1:你重新宣布方法(
new
); if you override
it should work. 如果你
override
它应该工作。 The new
breaks any polymorphic behavior. new
破坏了任何多态行为。
2: you are re-implementing the interface; 2:你正在重新实现界面; this indeed calls the highest implementation.
这确实称为最高的实施。 Again,
override
would fix this. 再次,
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";
}
}
Just make sure to declare the method that you want to be able to override as virtual. 只需确保声明您希望能够覆盖为虚拟的方法。 Then you use the override keyword on the inherited class.
然后在继承的类上使用override关键字。
Update 1: The new keyword is making explicit the fact, that just declaring a non virtual method on the inherited class will just hide the base method, when working with that class directly. 更新1:新关键字明确表示这样一个事实,即直接使用该类时,在继承的类上声明非虚方法只会隐藏基本方法。 Whenever you work with the base class, there is nothing to hide.
无论何时使用基类,都无需隐藏。
the new keywork and the override keyword do two very different things, and you are experiencing the behavior of new, where from your description I think you want to be using override as this follows the normally expected inherience behaviours. 新的keywork和override关键字执行两个非常不同的事情,并且您正在体验new的行为,从您的描述中我认为您希望使用override,因为这遵循通常预期的继承行为。 You will need to declare the method/property virtual in the base class and use override rather than new.
您需要在基类中声明方法/属性virtual并使用override而不是new。
doh, too slow! 啊,太慢了!
Implemented interface members are not automatically virtual. 已实现的接口成员不是自动虚拟的。 It's up to you to make them virtual, abstract, etc.
由你决定虚拟,抽象等等。
The reason your program does not do what you expect it to do is because of the new
keyword in your method. 您的程序没有按预期执行的原因是因为方法中的
new
关键字。
c# method are not dynamically bound by default. 默认情况下,c#方法不是动态绑定的。 This means the method that is called is determined at compile time.
这意味着调用的方法在编译时确定。 You can look at as the type of the variable determines which method is called instead of the actual object behind it in memory.
您可以查看变量的类型确定调用哪个方法而不是内存中的实际对象。
To achieve the effect you want, you need make sure c3 dynamically bind the method. 要获得所需的效果,您需要确保c3动态绑定方法。 you can do thing by declaring the method
virtual
and the overriding method override
. 你可以通过声明方法
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";
}
}
In general, never use new
on a method. 通常,永远不要在方法上使用
new
。 It almost never does what you want. 它几乎永远不会做你想要的。
I second Freddy Rios' point about the virtual keyword. 我第二个关于虚拟关键字的弗雷迪里奥斯的观点。 Unless your base class declares a method with the virtual keyword there will be no polymorphic behaviour at all.
除非你的基类使用virtual关键字声明一个方法,否则根本就没有多态行为。 It doesn't matter whether you use override or new.
无论您使用覆盖还是新建都无关紧要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.