The Inheritance Problem
Article Index
The Inheritance Problem
Solution

 

Solution

The problem is that as far as object oriented ideas go, there is only one MyMethod and overloads are all part of the same function entity.

All of the overloaded versions are a facility provided by the language that is something outside of the object oriented philosophy. So the derived class inherits just one MyMethod entity and the fact that this is overloaded is something implemented at a lower level.

That is, when the call:

Derived MyObject = new Derived();
MyObject.MyMethod(1);

is executed it first discovers that there is no local definition of MyMethod and then gets the Base implementation of MyMethod - which is overloaded. The overloading mechanism then selects the correct version of the method based on the call signature. The overloading mechanism comes after the inheritance - or if you like the entire overloaded set of functions is inherited as a job lot.

Now consider what happens when you move one of the overloaded definitions into the Derived class:

class Derived : Base
{
public void MyMethod(object i)
{
  MessageBox.Show("Derived Method Object");
}
}

Now there is a local definition of MyMethod and this hides the definition of the MyMethod in the base class - i.e. the entire overloaded set.

This is what causes the problem because as soon as you define MyMethod in the Derived class it no longer effectively inherits MyMethod from the Base class and this means that it doesn't get any of the overloaded versions.

You may think you are only redefining one of the overloaded versions i.e. MyMethod(int) but that's not how the object oriented inheritance sees it. As far as it is concerned there is only one MyMethod to inherit albeit overloaded...

Now seen in this light it is obvious that the refactoring breaks the overloading and you now only have MyMethod(object) in the Base class.

What is more you can'fix this even by overriding MyMethod(int) in the Derived class because there is nothing to override, i.e.. the redefinition of MyMethod effectively kills the inheritance. That is, if you refactor as:

class Base
{
public virtual void MyMethod(int i)
{
  MessageBox.Show("Base method Int");
}
}
class Derived : Base
{
public override  void MyMethod(int i)
{
  MessageBox.Show("Derived method Int");
}
public void MyMethod(object i)
{
  MessageBox.Show("Derived Method Object");
}
}

Then MyMethod(1) still calls the MyMethod(object) in the Derived class. The redefinition of MyMethod really does make the inheritance ineffective by hiding the inherited method. The override doesn't generate an error message because the override occures correctly but the method is hidden by the local redefinition.

Banner

Pattern

There really isn't any solution to this particular problem - inheritance and overloading don't play together well.

Classes inherit complete functions with any overloading or the function is hidden in its entirety by any local definition.

You can selectively override individual overloaded versions of an inherited method. For example:

class Base
{
 public virtual void MyMethod(int i)
{
  MessageBox.Show("Base method Int");
}
public virtual void MyMethod(object i)
{
  MessageBox.Show("Base Method Object");
}
}
class Derived : Base
{
 public override void MyMethod(object i)
{
  MessageBox.Show("Derived Method Object");
}
}

This works and a call to MyMethod(1) makes use of the Base classes MyMethod(int) function. This is because the MyMethod function is inherited, again in its entirety and you are just overriding, or not, different overloaded versions of it.

However, notice that this does not lead to a way of having more overloaded versions in the Derived class than in the Base class and so this doesn't actually solve the problem as posed.

As long as you think of inheritance as working in terms of just the function named and any overloading being implemented after the inheritance then it sort of makes sense and you are less likely to make the mistake.

 

Banner

More Puzzles

C++
A problem of order - constructor initialization

Initializers can be used to make constructors more elegant but they also introduce subtle problems. This brainteaser for C++ programmers illustrates a common pitfall.


PHP
A Question of Scope

PHP is sometimes a strange language when viewed from the perspective of other languages. This PHP puzzle demonstrates that you can't expect every language to work in the same way.


Python
Python Puzzle - Where Did The Time Go

A Python programming puzzle to get you up to speed. This one is all about time keeping, or is it? There are some strange things that go on in Python when you aren't paying attention. 


Other Articles

<ASIN:0321637003>

<ASIN:0596800959>

<ASIN:047043452X>

<ASIN:0123745144>



 
 

   
RSS feed of all content
I Programmer - full contents
Copyright © 2014 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.