为什么不能实现多个接口?

时间:2019-10-12 10:00:22

标签: java interface implements

我正在创建一个游戏,其中对象实现了动画接口。我有一个动画的父界面。这是简化版:

public interface Animates<S extends Animator> {
    S createAnimator(long animationTime);
}

此外,我有多个扩展此接口的接口。两个例子:

public interface AnimatesPaint extends Animates<PaintAnimator> {
    PaintAnimator createPaintAnimator(long animationTime);

    default PaintAnimator createAnimator(long animationTime) {
        return createPaintAnimator(animationTime);
    }

}

public interface AnimatesPosition extends Animates<PositionAnimator> {
    PositionAnimator createPositionAnimator(long animationTime);

    @Override
    default PositionAnimator createAnimator(long animationTime) {
        return createPositionAnimator(animationTime);
    }

}

如您所见,扩展Animates的接口将覆盖createAnimator方法,以便将createAnimator的逻辑委托给实现该接口的类。

之所以这样做,是因为我希望有一个可以实现多个动画界面的屏幕元素(可以进行动画处理)(例如,AnimatesPosition和元素{{1}一起移动) }来更改其颜色。

但是,这显然不起作用。当我在一个类中实现这两种方法时(如下图所示),我得到编译错误:

  AnimatesPaint中的

createAnimator(long)与发生冲突   AnimatesPosition中的createAnimator(long);尝试使用   不兼容的返回类型

这是同时实现两个Animates接口的类的示例:

AnimatesPaint

所以我不了解的是public class ScreenElement implements AnimatesPaint, AnimatesPosition { @Override PositionAnimator createPositionAnimator(long animationTime) { return new PositionAnimator(animationTime); } @Override PaintAnimator createPaintAnimator(long animationTime) { return new PaintAnimator(animationTime); } } AnimatesPaint都已经实现了AnimatesPosition。但是,错误消息似乎暗示createAnimator也需要实现createAnimator!如果ScreenElement尚未实现,我会明白的,为什么会发生冲突。

我的逻辑哪里出问题了?

最后,我要实现的是拥有一个可以启动任何类型动画的通用方法。例如:

createAnimator

-编辑-

应要求,这是Animator的声明

public class AnimationStarter<S extends Animates, T> {

    public void startAnimation(S animates, T start, T target, long animationTime) {
        Animator animator = animates.createAnimator(animationTime);
        animator.init(start, target);
        animates.setAnimator(animator);
        animator.startAnimation();
    }
}

及其扩展类之一

public abstract class Animator<T> {}

2 个答案:

答案 0 :(得分:4)

  

所以我不了解的是AnimatesPaintAnimatesPosition都已经实现了createAnimator

是,并且这些实现相互之间冲突。如果可以执行此操作,则结果类的类型将需要公开两个createAnimator方法,这些方法仅由返回类型来区分。 Java不允许您仅通过返回类型来区分重载,因此您不能这样做。为了重载,method signature不包含返回类型。

即使它们具有相同的返回类型(Animator),您也将拥有两个具有完全相同签名的重载,而这是不可以的。

如果它们要在同一类中实现,则它们需要是单独的方法,例如,具有可以区分的单独签名。


在评论中您已经询问:

  

但是,该方法是否已被AnimatesPaintAnimatesPosition覆盖的事实解决了冲突吗?这样,实现类ScreenElement不需要实现createAnimator方法,因此不会发生冲突。

否,因为类本身将这些方法(或者更确切地说,需要公开)作为其签名的一部分。基本上,假设您可以创建该类,并且有一个实例ss.createAnimator(300L)会做什么?编译器应该选择哪一个?

类的公共类型由其所有公共成员组成,包括其实现的所有接口的所有公共成员。因此,在类型级别上,两个接口不可能实现具有相同签名的方法。

答案 1 :(得分:2)

如果调用ScreenElements createAnimator()方法,应该使用哪个方法?这就是编译器所抱怨的。您需要告诉它在调用该方法时该怎么做。根据代码,我不确定。因此,您是正确的,ScreenElement需要实现create animator方法,这样编译器就知道在调用该方法时该怎么做。