Reputation:
Today, while implementing some testclasses in c#, I stumpled on some questions regarding inheritance (and interfaces) in 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:
Upvotes: 2
Views: 429
Reputation: 159
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. It doesn't matter whether you use override or new.
Upvotes: 0
Reputation: 1009
The reason your program does not do what you expect it to do is because of the new
keyword in your method.
c# method are not dynamically bound by default. 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. you can do thing by declaring the method virtual
and the overriding method 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. It almost never does what you want.
Upvotes: 0
Reputation: 15633
Implemented interface members are not automatically virtual. It's up to you to make them virtual, abstract, etc.
Upvotes: 0
Reputation: 29243
It's because you use the "new" modifier, see MSDN
You should use "override" instead
Upvotes: 0
Reputation: 1116
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. You will need to declare the method/property virtual in the base class and use override rather than new.
doh, too slow!
Upvotes: 0
Reputation: 36035
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.
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. Whenever you work with the base class, there is nothing to hide.
Upvotes: 1
Reputation: 1064114
1: you are re-declaring the method (new
); if you override
it should work. The new
breaks any polymorphic behavior.
2: you are re-implementing the interface; this indeed calls the highest implementation. Again, override
would fix this.
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";
}
}
Upvotes: 9