私は、オブジェクトがアニメーションのためのインタフェースを実装し、ゲームを作成しています。私はアニメーションのための親のインタフェースを持っています。ここでは短縮バージョンは以下のとおりです。
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);
}
}
それでは、私は理解していないことの両方ということです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();
}
}
--Edit--
要求に応じて、ここでアニメーターの宣言です
public abstract class Animator<T> {}
およびその拡張クラスの一つ
public class PositionAnimator extends Animator<Point>{}
それでは、私は理解していないことの両方ということです
AnimatesPaint
とAnimatesPosition
、すでに実装しますcreateAnimator
。
はい、それらの実装の競合互いに。あなたがこれを行うことができれば、あなたの結果のクラスの型が2つの公開する必要があるだろうcreateAnimator
唯一の戻り値の型によって区別されている方法を。Javaは、あなたがそれを行うことはできませんのでだけ、戻り値の型によって区別されているオーバーロードを持たせません。メソッドシグネチャは、過負荷の目的のために、戻り値の型が含まれていません。
彼らは(同じ戻り値の型を持っていたとしてもAnimator
)、あなたは、あなたが行うことはできません正確に同じシグネチャ、と2つのオーバーロードがあるだろう。
例えば、区別することができる独立したシグネチャを持つ - - 彼らは同じクラスに実装するつもりなら、彼らは別の方法である必要があります。
コメントでは、求めてきました:
しかし、競合が方法がすでにによって上書きされたことによって解決されていない
AnimatesPaint
とAnimatesPosition
?この方法では、実装クラスがScreenElement
実装する必要はありませんcreateAnimator
方法を、ので、競合は発生しません。
いいえ、クラス自体は、その署名の一部として(またはむしろ、する必要がある)これらのメソッドを公開するからです。基本的に、あなたはクラスを作成することができたと、あなたは、それのインスタンスを持っていましたs
。何をするでしょうs.createAnimator(300L)
か?コンパイラは、どちらを選ぶべきなのでしょうか?
クラスの公開型は、それが実装するインタフェースのすべてのすべてのパブリックメンバーを含む、そのパブリックメンバーのすべてで構成されています。二つのインタフェースは、同じシグネチャを持つメソッドを実装するので、タイプレベルで、それは不可能です。