[英]Why can't I implement multiple interfaces?
I am creating a game where objects implement interfaces for animations.我正在创建一个游戏,其中对象实现动画接口。 I have a parent interface for the animations.
我有动画的父界面。 Here is a shortened version:
这是一个缩短的版本:
public interface Animates<S extends Animator> {
S createAnimator(long animationTime);
}
In addition, I have multiple interfaces that extend this interface.另外,我有多个扩展这个接口的接口。 Two examples:
两个例子:
public interface AnimatesPaint extends Animates<PaintAnimator> {
PaintAnimator createPaintAnimator(long animationTime);
default PaintAnimator createAnimator(long animationTime) {
return createPaintAnimator(animationTime);
}
}
and和
public interface AnimatesPosition extends Animates<PositionAnimator> {
PositionAnimator createPositionAnimator(long animationTime);
@Override
default PositionAnimator createAnimator(long animationTime) {
return createPositionAnimator(animationTime);
}
}
As you can see, the interfaces that extend Animates
override the createAnimator
method in order to delegate the logic of createAnimator
to the class that implements the interface.如您所见,扩展
Animates
的接口覆盖了createAnimator
方法,以便将createAnimator
的逻辑委托给实现该接口的 class。
The reason I am doing this is that I want to be able to have a screen element (that can animate) that implements multiple animation interfaces (for example both AnimatesPosition
to move the element around and AnimatesPaint
to change its color).我这样做的原因是我希望能够拥有一个实现多个 animation 接口的屏幕元素(可以动画)(例如,用于移动元素的
AnimatesPosition
和用于更改其颜色的AnimatesPaint
)。
However, that apparently does not work.然而,这显然行不通。 When I implement both in one class (illustrated below), I get the compilation error:
当我在一个 class(如下图所示)中实现两者时,我得到编译错误:
createAnimator(long) in AnimatesPaint clashes with createAnimator(long) in AnimatesPosition;
AnimatesPaint 中的 createAnimator(long) 与 AnimatesPosition 中的 createAnimator(long) 发生冲突; attempting to use incompatible return types
尝试使用不兼容的返回类型
Here is an example of a class that implements both Animates interfaces:下面是实现两个 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);
}
}
So what I don't understand is that both AnimatesPaint
and AnimatesPosition
already implement createAnimator
.所以我不明白的是
AnimatesPaint
和AnimatesPosition
都已经实现了createAnimator
。 Yet, the error message seems to suggest that createAnimator
also needs to be implemented by ScreenElement
!然而,错误消息似乎表明
createAnimator
也需要由ScreenElement
实现! If createAnimator
would not have been implemented yet, I would get it, why there is a clash.如果
createAnimator
还没有实现,我会明白的,为什么会有冲突。
Where does my logic go wrong?我的逻辑 go 哪里错了?
In the end, what I want to achieve, is to have a generic method that can initiate any type of animation.最后,我想要实现的是有一个通用的方法,可以启动任何类型的 animation。 For example:
例如:
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();
}
}
--Edit-- - 编辑 -
Upon request, here is the declaration of Animator根据要求,这里是 Animator 的声明
public abstract class Animator<T> {}
and one of its extended classes及其扩展类之一
public class PositionAnimator extends Animator<Point>{}
So what I don't understand is that both
AnimatesPaint
andAnimatesPosition
already implementcreateAnimator
.所以我不明白的是
AnimatesPaint
和AnimatesPosition
都已经实现了createAnimator
。
Yes, and those implementations conflict with one another.是的,这些实现相互冲突。 If you could do this, your resulting class's type would need to expose two
createAnimator
methods that are only differentiated by return type.如果可以这样做,则生成的类的类型将需要公开两个仅通过返回类型区分的
createAnimator
方法。 Java doesn't let you have overloads that are only differentiated by return type, so you can't do that. Java 不允许您拥有仅按返回类型区分的重载,因此您不能这样做。 A method signature , for overloading purposes, doesn't include the return type.
用于重载目的的方法签名不包括返回类型。
Even if they had the same return type ( Animator
), you'd then have two overloads with exactly the same signature, which you can't do.即使它们具有相同的返回类型(
Animator
),您也会有两个具有完全相同签名的重载,这是您无法做到的。
They'll need to be separate methods — eg, with separate signatures that can be differentiated — if they're going to be implemented in the same class.如果它们要在同一个 class 中实现,它们将需要是单独的方法——例如,具有可以区分的单独签名。
In a comment you've asked:在您问过的评论中:
But isn't the conflict resolved by the fact that the method has already been overriden by
AnimatesPaint
andAnimatesPosition
?但是,该方法是否已被
AnimatesPaint
和AnimatesPosition
覆盖这一事实是否解决了冲突? This way the implementing classScreenElement
doesn't need to implementcreateAnimator
method, so no conflict will occur.这样实现 class
ScreenElement
不需要实现createAnimator
方法,所以不会发生冲突。
No, because the class itself exposes those methods (or rather, would need to) as part of its signature.不,因为 class 本身公开了这些方法(或者更确切地说,需要)作为其签名的一部分。 Basically, suppose you could create the class and you had an instance of it,
s
.基本上,假设您可以创建 class 并且您有一个实例
s
。 What would s.createAnimator(300L)
do? s.createAnimator(300L)
会做什么? Which one should the compiler choose?编译器应该选择哪一个?
A class's public type is composed of all of its public members, including all the public members of all of the interfaces it implements.一个类的公共类型由它的所有公共成员组成,包括它实现的所有接口的所有公共成员。 So at a type level, it's impossible for two interfaces to implement methods with the same signature.
所以在类型级别上,两个接口不可能实现具有相同签名的方法。
If you call ScreenElements createAnimator() method, which one is it supposed to use?如果你调用 ScreenElements createAnimator() 方法,它应该使用哪一个? That's what the compiler is complaining about.
这就是编译器所抱怨的。 You need to tell it what to do when that method is called.
您需要告诉它在调用该方法时要做什么。 Based on the code I'm not sure.
根据我不确定的代码。 So you are correct that ScreenElement needs to implement the create animator method, that way the compiler knows what to do when that method is called.
所以你是正确的 ScreenElement 需要实现 create animator 方法,这样编译器就知道在调用该方法时要做什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.