Remove inheritance but keep polymorphism?

Hi guys,

over the years our code has gotten very complex and there are some very long inheritance chains. I would like to break this up using composition. e.g.

class V1

{

publicvoid doSomethingElse()

{

}

public V1()

{

doSomethingElse();

}

}

class V2extends V1

{

public V2()

{

super();

}

//Overridden method used in constructor of super class

publicvoid doSomethingElse()

{

//Does something different to the one above

}

}

So I want to refactor this using composition so that V2 looks something like this

class V2

{

private V1 _v1;

public V2()

{

_v1 =new V1();

}

//Overridden method used in constructor of super class

publicvoid doSomethingElse()

{

//Does something different to the one above

}

But as you can see from this, the doSomethingElse() method in V2 will never be called because you've removed inheritance.

Does anybody know a simple way to get around this overridden method problem when removing inheritance?

Thanks.

[2265 byte] By [stcinifeica] at [2007-10-3 0:35:32]
# 1
Yes, place the method in an interface that the class will implement.- Saish
Saisha at 2007-7-14 17:29:17 > top of Java-index,Other Topics,Patterns & OO Design...
# 2

You should not be calling overrideable methods in constructors. This is a huge error waiting to blow up in your face.Get rid of that with extreme prejudice.

I dont see how you can keep that dosomethingelse system going once you stop calling overrideable methods from your constructor. why not just put the whole 'dosomethingelse' method directly in the constructor?

_dnoyeBa at 2007-7-14 17:29:17 > top of Java-index,Other Topics,Patterns & OO Design...
# 3

Hi,

Yes but the problem is more general than just constructors.

For example. X, and Y which extends X. X implements SomeInterface, which contains the method myMethod(). myMethod is only in X, but calls a method (doMyThing()) that is overridden in Y.

I want to remove inheritance by using composition, which means that Y has to implement SomeInterface as well, and also put a reference to X in Y.

For example:

public interface SomeInterface()

{

public void myMethod();

}

public class X implements SomeInterface

{

public void myMethod()

{

doMyThing();

}

public void doMyThing()

{

//Do something in here

}

}

public class Y implements SomeInterface

{

//Replace extension with composition

X _x;

public void myMethod()

{

//Fixes inheritance problem, but doesn't fix the polymorphism problem because it's always X.doMyThing() that will be called.

_x.myMethod();

}

public void doMyThing()

{

//Do something different to X in here

}

}

So now you have someone calling this stuff from outside...

SomeInterface temp = new Y();//Assume constructor stuff is ok.

temp.myMethod(); //Overridden Y's doMyThing() will never be called

I'm just wondering if there's a quick and easy way to get the polymorphism back in without loads of redundant code and without having to go back to inheritance.

I was thinking along the lines of finding out all the methods which have been overridden in the inheritance chain, and then pass the current "this" to each of these methods so that when it comes to the overridden method call in the code, it can be called on the passed "this" to ensure the correct (in this case "doMyThing") method can be called.

e.g.

public interface SomeInterface()

{

public void myMethod(SomeInterface si);

public void doMyThing();

}

public class X implements SomeInterface

{

public void myMethod(SomeInterface si)

{

si.doMyThing();

}

public void doMyThing()

{

//Do something in here

}

}

public class Y implements SomeInterface

{

//Replace extension with composition

X _x;

public void myMethod(SomeInterface si)

{

//This will make sure the correct doMyThing() will get called but is it the best way?

_x.myMethod(this);

}

public void doMyThing()

{

//Do something different to X in here

}

}

But is there a better way?

Thanks!

stcinifeica at 2007-7-14 17:29:17 > top of Java-index,Other Topics,Patterns & OO Design...
# 4

No, thats will not work. You started with the template method pattern. You can not change that to using composition and still maintain the template method pattern. (without jumping through hoops)

Do you have a good reason for trying to use composition? I wouldn't use it here if I had a choice. Its going to be more complex and less clear. Or you can dump the template method pattern.

_dnoyeBa at 2007-7-14 17:29:17 > top of Java-index,Other Topics,Patterns & OO Design...