Home > Net >  In Java, is it OK to require classes that implement an interface to inherit from a specific base cla
In Java, is it OK to require classes that implement an interface to inherit from a specific base cla

Time:04-19

Quick style question:

I have a Java interface that defines functions that must be implemented by classes in a particular hierarchy, all descended from a specific base class.

There are contexts where I will be dealing with these classes through a pointer to the interface, but I need a pointer to the base class instead.

Example:

public class Base {}

public interface ChildRequirements {
    Base asBase();
}

public class Child extends Base implements ChildRequirements {
    Base asBase() { return this; }
}

public class SomeClass {
    public void doSomething(Base base) { }

    public void doSomethingElse(ChildRequirements creqt) {
        doSomething(creqt.asBase());
    }
}

Is this bad form? Am I thinking about this the wrong way? Should I just cast creqt as Base and ignore the warnings?

CodePudding user response:

I have a Java interface that defines functions that must be implemented by classes in a particular hierarchy, all descended from a specific base class.

Then it isn't an interface, it's an abstract base class. Get rid of ChildRequirements and instead have Base define the requirements and mark it abstract:

abstract public class Base {
    // ...required methods here, `abstract` if you don't have a
    // base implementation...
}

public class Child extends Base {
    // ...implements any `abstract` methods...
}

public class SomeClass {
    public void doSomething(Base base) { }

    public void doSomethingElse(Base creqt) {
        doSomething(creqt);
    }
}

But whenever possible, program to interfaces, not abstract classes.

CodePudding user response:

I don't see the difference between your typing and just using interfaces and ol'regular inheritance. Your return this in the Child class seems to suggest you expect it to be a subtype of Base. The way the interfaces are structured it seems like you are actually expressing an is-a relationship between Base and ChildRequirements, but decorating the super class.

Alternate typing:

//Straight-forware inheritance
public interface Base {
    
}

interface ChildRequirements extends Base{
    Base asBase();//return the super
}

class Child implements ChildRequirements {
    public Base asBase() { return this;}
}

class SomeClass {

    public void doSomething(Base base) { }

    public void doSomethingElse(ChildRequirements creqt) {
            doSomething(creqt.asBase());
    }
    

}
  • Related