Deep C# - Inheritance
Written by MIke James   
Thursday, 27 August 2020
Article Index
Deep C# - Inheritance
Changing Types
Hiding Methods
Summary

Hiding methods

There is just a little more to say about inheritance in C# because if you don’t declare a method as virtual then overriding it isn’t quite as simple as in C++, say. C# doesn’t really have a default overriding method. If you declare a class and a method as:

class A
{
void method()
{
A’s version of the function;
}
}

and derive a class B from A then a C++ programmer might well override the method using:

class B:A
{
void method()
{
B’s version of the function;
}
}

This works but it generates a warning. The reason is that C# expects you to use the “new” keyword if you are redefining an inherited function:

class B:A
{
new void method()
{
B’s version of the function;
}
}

This also works but without generating a warning.

In the C# reference manual this use of ‘new’ is said to ‘hide’ the inherited method. What this means is that the new definition is used in preference to the old one wherever it is in scope, i.e. wherever its definition applies. This appears to work just like overriding a non-virtual method but there are some subtleties. For example:

B MyB=new B();
MyB.method();

uses the new class B method. However if you use

B MyB;
MyB=new A();
MyB.method();

then A’s original version of method is called.

This isn’t unreasonable as the original method wasn’t declared as virtual and so you wouldn’t expect late binding/polymorphism to work.

However the subtle part is that it still doesn’t work even if the original method was declared as virtual!

In other words the “new” keyword kills virtual inheritance! If you derive a class C from B and use the “override” keyword on a new version of the method then virtual inheritance works again.

The final twist is that the effect of the “new” keyword depends on whether or not the method is accessible. For example, if you declare the new method as private it only overrides the inherited method within the class – when used outside the class the inherited method is once again called.

Finally – why is the “new” keyword needed and why is only a warning generated when you forget to use it?

The reason is that you might very well create a class B that inherits from A and give it a new method called MyMethod. This method doesn’t need a “new” or an “override” keyword because it isn’t hiding or overriding an inherited method – it really is new. Everything is fine but suppose that later on class A is modified independently of class B and it has a MyMethod function added to it. Now there is a name collision between B.MyMethod and A.MyMethod. By default the B class always uses its own MyMethod which is presumably what its programmer would have wanted since they couldn’t have guessed that the owner of class A would add a MyMethod! Of course when the owner of class B recompiles the code they will be greeted with a warning that lets them know about the change. They can then either add the “new” keyword or “override” as appropriate.

Interfaces and multiple inheritance

Before we leave the topic of inheritance it is worth considering the potentially confusing idea of an ‘interface’.

Banner

Superficially an interface is like a class in that it can be inherited. The C# syntax is even very similar. For example to define an interface with a single method you would write:

public interface IMyInterface
{
void MyMethod(int value);
}

An interface can only define methods and not fields or properties. IMyInterface looks like a class and indeed it can be inherited. For example:

public class MyClass:IMyInterface{}

This looks a lot like simple inheritance but - and this is the important difference – MyClass doesn’t inherit any implementation details from IMyInterface. That is, if you try to create a MyClass object without doing anything about the Interface:

MyClass MyObject=new MyClass();

you can’t call MyMethod using:

MyObject.MyMethod

In fact you can’t even create MyObject unless you write some code that implements all of the methods defined in the interface.

That is, to make the previous example work you would have to define MyClass as:

public class MyClass:IMyInterface{
void IMyInterface.MyMethod(int value)
{
code that does something
}
}

You don’t have to specify the interface method as IMyInterface.MyMethod if there isn’t any chance of a name clash but it’s a good habit to get into. In this case it looks as if MyMethod is being overridden by a new definition provided by IMyInterface.MyMethod. This isn’t really true as there is no implementation of MyMethod provided for you to override!



Last Updated ( Thursday, 27 August 2020 )