覆盖扩展接口中的返回类型 – 不好主意?

在Java中,您可以执行以下操作:

public interface IEngine{} public interface ICoolEngine extends IEngine{} public interface Car { IEngine getEngine(); } public interface ICoolCar extends ICar { @Override ICoolEngine getEngine(); } 

虽然这很好地解决了我一直在努力解决的问题,但有些事情“感觉”错了。

我在这里做了一些讨厌的设计失礼吗?

不,你正在做正确的事。 Covariant返回只是指定类及其下面的类必须返回父类返回的原始通用类参数的特定子类。 它还意味着您的子类仍然需要返回引擎的原始接口兼容,但如果您知道它是ICoolCar,那么它具有ICoolEngine – 因为更具体的接口知道更具体的function。 这适用于接口和类 – 这是正确的,适当的和有用的启动。

不,那没关系。 由于ICoolEngine扩展了IEngine ,任何实现ICoolEngine对象ICoolEngine可以被视为IEngine (当然没有所有的ICoolEngine特定方法)。 您只需要知道类型的不同取决于您在每种情况下使用的接口,并确保不使用ICoolEngine方法(假设在您的实际代码中,有ICoolEngine中等效的其他方法。

这样做并不是一个坏习惯; 你只是在使用多态的力量。

协变返回类型是一个故意的function,在1.5中添加(主要支持generics)。

@Override可能不适用于使用某些编译器覆盖抽象方法(javac在1.6中更新,但JLS修订版被遗漏了)。

一如既往地向接口添加方法会带来兼容性问题。 完全按照超类型重新声明方法可以,但更改返回类型会导致实现类中的桥接方法。 这就是Iterable.iterator不返回Iterator接口的只读版本的原因。

你正在做的事情完全没问题。

我更喜欢这样说:

 public interface IEngine { } public interface ICoolEngine extends IEngine { } public interface ICar { T getEngine(); } public interface ICoolCar extends ICar { } 

我使用generics,因为当你使用注释我猜你正在研究Java 5+