Flot2011
Flot2011

Reputation: 4671

Java - extending the whole class hierarchy

I have a class hierarchy like that:

abstract class BaseThing
{
    public abstract void doSomething();
}

class Thing1 extends BaseThing
{
    @Override
    public void doSomething()
    {
        doSomethingWithThing1();
    }
}

class Thing2 extends BaseThing
{
    @Override
    public void doSomething()
    {
        doSomethingWithThing2();
    }
}

// A dozen more classes that extend the BaseThing class. 

I need to create an extended version of the whole tree. There is no multiple inheritance in Java, so I created it as:

interface BaseThingExt
{
   public void doSomethingElse();
}

class Thing1Ext extends Thing1 implements BaseThingExt
{
    @Override
    public void doSomethingElse()
    {
        doSomethingElseWithThing1();
    }
}

//   All Thing.. classes are extended by ThingExt... classes

Now the question. Where can I put some common fields for all ThingExt classes? I cannot place them in the base interface, as they would become final static. I cannot make BaseThingExt an abstract class as Java doesn't support a multiple inheritance. I cannot believe the only solution is to replicate them a dozen times in all ThingExt classes!

EDIT: Please note that all ThingExt classes should extend their according Thing classes and not just the BaseThing class, because there are some specifics in each derived class. So the answer by @Hamdi Douss won't work.

Upvotes: 2

Views: 734

Answers (2)

Hamdi Douss
Hamdi Douss

Reputation: 1113

I suggest to add a super class AbstractBaseThingExt:

abstract class AbstractBaseThingExt implements BaseThingExt
{
    private Object commonField;
    public Object getCommonField(){}
    public Object setCommonField(Object commonField){}
}

class ThingExt extends AbstractBaseThingExt
{
    public ThingExt(BaseThing base) {
        this.base = base;
    }

    public void doSomething()
    {
        this.base.doSomething();
    }
}

The class ThingExt should delegate implementation to base when appropriate.

Upvotes: 3

JB Nizet
JB Nizet

Reputation: 691785

The usual trick is to use composition rather than inheritance:

interface BaseThingExt
{
   public void doSomethingElse();
}

class ConcreteImplementation implements BaseThing, BaseThingExt {

    private final BaseThing thingDelegate;
    private final BaseThingExt extDelegate;

    public ConcreteImplementation(BaseThing thing, BaseThingExt ext) {
        this.thingDelegate = thing;
        this.extDelegate = ext;
    }


    @Override
    public void doSomething() {
        thingDelegate.doSomething();
    }

    @Override
    public void doSomethingElse() {
        extDelegate.doSomethingElse();
    }
}

Upvotes: 7

Related Questions