为什么我不能实现多个接口?
Why can't I implement multiple interfaces?
我正在创建一个对象实现动画接口的游戏。我有一个动画的父界面。这是一个简化版本:
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
的逻辑委托给实现该接口的 class .
我这样做的原因是我希望能够有一个屏幕元素(可以动画)实现多个动画界面(例如 AnimatesPosition
移动元素和 AnimatesPaint
改变颜色)。
但是,这显然行不通。当我在一个 class 中实现两者时(如下图所示),我得到了编译错误:
createAnimator(long) in AnimatesPaint clashes with
createAnimator(long) in AnimatesPosition; attempting to use
incompatible return types
这是一个实现了两个 Animates 接口的 class 示例:
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
还没有实现,我就明白了,为什么会有冲突。
我的逻辑哪里出了问题?
最后,我想要实现的是有一个通用的方法,可以启动任何类型的动画。例如:
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();
}
}
--编辑--
根据要求,这里是 Animator 的声明
public abstract class Animator<T> {}
及其扩展之一 classes
public class PositionAnimator extends Animator<Point>{}
So what I don't understand is that both AnimatesPaint
and AnimatesPosition
already implement createAnimator
.
是的,而且这些实现相互冲突。如果你能做到这一点,你得到的 class 类型将需要公开两个 createAnimator
方法,它们仅由 return 类型区分。 Java 不允许您拥有仅由 return 类型区分的重载,因此您不能那样做。 method signature,出于重载目的,不包括 return 类型。
即使它们具有相同的 return 类型 (Animator
),您也会有两个具有完全相同签名的重载,这是您做不到的。
如果它们要在相同的 class.
中实现,它们将需要是单独的方法——例如,具有可以区分的单独签名
在您提出的评论中:
But isn't the conflict resolved by the fact that the method has already been overriden by AnimatesPaint
and AnimatesPosition
? This way the implementing class ScreenElement
doesn't need to implement createAnimator
method, so no conflict will occur.
不,因为 class 本身公开了这些方法(或者更确切地说,需要)作为其签名的一部分。基本上,假设您可以创建 class 并且您有一个实例 s
。 s.createAnimator(300L)
会做什么?编译器应该选择哪一个?
class 的 public 类型由其所有 public 成员组成,包括其实现的所有接口的所有 public 成员。所以在类型级别,两个接口不可能实现具有相同签名的方法。
如果调用 ScreenElements 的 createAnimator() 方法,应该使用哪一个?这就是编译器所抱怨的。您需要告诉它在调用该方法时要做什么。根据代码,我不确定。所以你是正确的,ScreenElement 需要实现 create animator 方法,这样编译器就知道在调用该方法时要做什么。
我正在创建一个对象实现动画接口的游戏。我有一个动画的父界面。这是一个简化版本:
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
的逻辑委托给实现该接口的 class .
我这样做的原因是我希望能够有一个屏幕元素(可以动画)实现多个动画界面(例如 AnimatesPosition
移动元素和 AnimatesPaint
改变颜色)。
但是,这显然行不通。当我在一个 class 中实现两者时(如下图所示),我得到了编译错误:
createAnimator(long) in AnimatesPaint clashes with createAnimator(long) in AnimatesPosition; attempting to use incompatible return types
这是一个实现了两个 Animates 接口的 class 示例:
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
还没有实现,我就明白了,为什么会有冲突。
我的逻辑哪里出了问题?
最后,我想要实现的是有一个通用的方法,可以启动任何类型的动画。例如:
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();
}
}
--编辑--
根据要求,这里是 Animator 的声明
public abstract class Animator<T> {}
及其扩展之一 classes
public class PositionAnimator extends Animator<Point>{}
So what I don't understand is that both
AnimatesPaint
andAnimatesPosition
already implementcreateAnimator
.
是的,而且这些实现相互冲突。如果你能做到这一点,你得到的 class 类型将需要公开两个 createAnimator
方法,它们仅由 return 类型区分。 Java 不允许您拥有仅由 return 类型区分的重载,因此您不能那样做。 method signature,出于重载目的,不包括 return 类型。
即使它们具有相同的 return 类型 (Animator
),您也会有两个具有完全相同签名的重载,这是您做不到的。
如果它们要在相同的 class.
中实现,它们将需要是单独的方法——例如,具有可以区分的单独签名在您提出的评论中:
But isn't the conflict resolved by the fact that the method has already been overriden by
AnimatesPaint
andAnimatesPosition
? This way the implementing classScreenElement
doesn't need to implementcreateAnimator
method, so no conflict will occur.
不,因为 class 本身公开了这些方法(或者更确切地说,需要)作为其签名的一部分。基本上,假设您可以创建 class 并且您有一个实例 s
。 s.createAnimator(300L)
会做什么?编译器应该选择哪一个?
class 的 public 类型由其所有 public 成员组成,包括其实现的所有接口的所有 public 成员。所以在类型级别,两个接口不可能实现具有相同签名的方法。
如果调用 ScreenElements 的 createAnimator() 方法,应该使用哪一个?这就是编译器所抱怨的。您需要告诉它在调用该方法时要做什么。根据代码,我不确定。所以你是正确的,ScreenElement 需要实现 create animator 方法,这样编译器就知道在调用该方法时要做什么。