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

时间:2009-05-14 17:07:57

标签: java oop

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

public interface IEngine{}
public interface ICoolEngine extends IEngine{}

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

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

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

4 个答案:

答案 0 :(得分:15)

不,你做的是对的。 Covariant返回只是指定类及其下面的类必须返回父类返回的原始通用类参数的特定子类。这也意味着您的子类仍然需要返回引擎的原始接口兼容,但是如果您知道它是一个ICoolCar,它有一个ICoolEngine - 因为更具体的接口知道更具体的功能。这适用于接口和类 - 这对于引导来说是正确的,正确的和有用的。

答案 1 :(得分:3)

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

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

答案 2 :(得分:2)

协变返回类型是一个故意的功能,在1.5中添加(主要用于支持泛型)。

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

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

答案 3 :(得分:0)

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

我更喜欢这样说:

public interface IEngine { }
public interface ICoolEngine extends IEngine { }

public interface ICar<T extends IEngine> {
   T getEngine();
}

public interface ICoolCar extends ICar<ICoolEngine> { }

我使用了泛型,因为当你使用注释我猜你正在使用Java 5 +