'In Java, is it OK to require classes that implement an interface to inherit from a specific base class?
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?
Solution 1:[1]
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.
Solution 2:[2]
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());
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | T.J. Crowder |
| Solution 2 | cogitoboy |
