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());
}
}