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

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

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可以移动元素,而AnimatesPaint可以更改其颜色)。

但是,这显然行不通。当我在一个类中实现这两者时(如下图所示),我得到编译错误:

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

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

public class ScreenElement implements AnimatesPaint, AnimatesPosition {
    @Override
    PositionAnimator createPositionAnimator(long animationTime) {
        return new PositionAnimator(animationTime);
    }
    @Override
    PaintAnimator createPaintAnimator(long animationTime) {
        return new PaintAnimator(animationTime);
    }
}

所以我不明白的是AnimatesPaintAnimatesPosition已经实现了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> {}

及其扩展类之一

public class PositionAnimator extends Animator<Point>{}

参考方案

所以我不明白的是AnimatesPaintAnimatesPosition已经实现了createAnimator

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

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

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

在评论中,您询问:

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

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

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

Java:线程池如何将线程映射到可运行对象 - java

试图绕过Java并发问题,并且很难理解线程池,线程以及它们正在执行的可运行“任务”之间的关系。如果我创建一个有10个线程的线程池,那么我是否必须将相同的任务传递给池中的每个线程,或者池化的线程实际上只是与任务无关的“工人无人机”可用于执行任何任务?无论哪种方式,Executor / ExecutorService如何将正确的任务分配给正确的线程? 参考方案 …

JAVA:字节码和二进制有什么区别? - java

java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

Java:BigInteger,如何通过OutputStream编写它 - java

我想将BigInteger写入文件。做这个的最好方式是什么。当然,我想从输入流中读取(使用程序,而不是人工)。我必须使用ObjectOutputStream还是有更好的方法?目的是使用尽可能少的字节。谢谢马丁 参考方案 Java序列化(ObjectOutputStream / ObjectInputStream)是将对象序列化为八位字节序列的一种通用方法。但…

Java DefaultSslContextFactory密钥库动态更新 - java

我有一个使用org.restlet.engine.ssl.DefaultSslContextFactory的现有应用程序和一个在服务器启动时加载的密钥库文件。我有另一个应用程序,该应用程序创建必须添加的证书服务器运行时动态地更新到密钥库文件。为此,我在代码中创建了证书和私钥,然后将其写入到目录。该目录由bash脚本监视,该脚本检查是否有新文件,如果出现,它将…