In Java, you can do the following :
public interface IEngine{}
public interface ICoolEngine extends IEngine{}
public interface Car
{
IEngine getEngine();
}
public interface ICoolCar extends ICar
{
@Override
ICoolEngine getEngine();
}
While this nicely solves a problem I've been grappling with, something about it "feels" wrong.
Am I committing some nasty design faux pas here?
No, you are doing the right thing. Covariant returns just specify that the class, and classes below it, must return a specific subclass of the original general class argument that the parent class returned. It also means that your subclasses are still compatible with the original interface that requires that it return an Engine, but if you know that it is an ICoolCar, that it has an ICoolEngine - because the more specific interface knows of more specific functionality. This applies to interfaces as well as classes - this is correct, proper and useful to boot.
No, that's fine. Since ICoolEngine
extends IEngine
, any object implementing ICoolEngine
can be treated as if it's an IEngine
(without all the ICoolEngine
-specific methods of course). You'll just have to be aware of the type difference depending on which interface you are working with in each situation, and make sure not to use ICoolEngine
methods that aren't defined in IEngine
(assuming that, in your actual code, there are additional methods listed in the equivalent of ICoolEngine
).
It's not a bad practice to do this; you're simply using the power of polymorphism.
Covariant return types is a deliberate feature that was added in 1.5 (to support generics primarily).
@Override may not work for overriding abstract methods with some compilers (javac was updated in 1.6, but the JLS amendment was missed out).
As always adding an method to an interface risks compatibility issues. Redeclaring a method exactly as in the super-type would be fine, but changing the return type causes a bridge method in implementation classes. This is why Iterable.iterator
does not return a read-only version of the Iterator
interface.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With