なぜ私は、複数のインターフェイスを実装することはできませんか?

MWB:

私は、オブジェクトがアニメーションのためのインタフェースを実装し、ゲームを作成しています。私はアニメーションのための親のインタフェースを持っています。ここでは短縮バージョンは以下のとおりです。

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その色を変更します)。

しかし、ことは明らかに動作しません。私は1つのクラス(下記に示す)の両方を実装するとき、私はコンパイルエラーが出ます:

AnimatesPositionでcreateAnimator(長い)とAnimatesPaintの衝突でcreateAnimator(長いです)。互換性のない戻り値の型を使用しようとします

ここで実装両方のアニメーションインターフェースそのクラスの例です。

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();
    }
}

--Edit--

要求に応じて、ここでアニメーターの宣言です

public abstract class Animator<T> {}

およびその拡張クラスの一つ

public class PositionAnimator extends Animator<Point>{}
TJクラウダー:

それでは、私は理解していないことの両方ということですAnimatesPaintAnimatesPosition、すでに実装しますcreateAnimator

はい、それらの実装の競合互いに。あなたがこれを行うことができれば、あなたの結果のクラスの型が2つの公開する必要があるだろうcreateAnimator唯一の戻り値の型によって区別されている方法を。Javaは、あなたがそれを行うことはできませんのでだけ、戻り値の型によって区別されているオーバーロードを持たせません。メソッドシグネチャは、過負荷の目的のために、戻り値の型が含まれていません。

彼らは(同じ戻り値の型を持っていたとしてもAnimator)、あなたは、あなたが行うことはできません正確に同じシグネチャ、と2つのオーバーロードがあるだろう。

例えば、区別することができる独立したシグネチャを持つ - - 彼らは同じクラスに実装するつもりなら、彼らは別の方法である必要があります。


コメントでは、求めてきました:

しかし、競合が方法がすでにによって上書きされたことによって解決されていないAnimatesPaintAnimatesPositionこの方法では、実装クラスがScreenElement実装する必要はありませんcreateAnimator方法を、ので、競合は発生しません。

いいえ、クラス自体は、その署名の一部として(またはむしろ、する必要がある)これらのメソッドを公開するからです。基本的に、あなたはクラスを作成することができたと、あなたは、それのインスタンスを持っていましたs何をするでしょうs.createAnimator(300L)か?コンパイラは、どちらを選ぶべきなのでしょうか?

クラスの公開型は、それが実装するインタフェースのすべてのすべてのパブリックメンバーを含む、そのパブリックメンバーのすべてで構成されています。二つのインタフェースは、同じシグネチャを持つメソッドを実装するので、タイプレベルで、それは不可能です。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=311689&siteId=1