2016-04-02 19 views
3

宣言型/拡張型のクラスを返す型のインターフェイス/抽象メソッドを作成する方法を探していました。 (たとえば、classAはinterfaceAを拡張し、メソッドはClassAオブジェクトを返す必要があります)。インタフェース/抽象メソッドの戻り型としてのJava拡張クラス

コンパイラがそのようなことについて文句を言わないポストを見つけましたが、JVMはこのようなことを処理できません。この整備士はjavaには存在しません。

私はそれが技術的に十分であるかどうかわからないから、次のアイデアを思いついた。 (ループを引き起こすなど)

public interface ISomeInterface<T extends ISomeInterface<T>> { 
    public T get(); 
} 

このように使用することができます。これは拡張クラスを使用する外部ユーザーを強制doesntのが、それは少なくとも好まあればそうする機会を与えてくれます:

public class ExtendingClass implements ISomeInterface<ExtendingClass>{ 
    @Override 
    public ExtendingClass get(){} 
} 

さて、これは何のコンパイラやランタイムエラーを与えていないが、これは作成した場合、私は心配します広範に使用されていれば問題ありません。

誰かがこれが問題の原因かどうかを確認できたらうれしいです。 (他のフィードバックも歓迎されます)。

+2

これはうまく動作すると思います。これは、Javaが 'enum'型に使用するのと同じパターンです。このパターンは[public class Enum >(https://docs.oracle.com/javase/8/docs/api/java/lang)として宣言されています。 /Enum.html) – markspace

+0

これはどのようにしてコンパイルエラーを生じさせませんか?実装クラスは抽象クラスではないため、このためのメソッド本体が必要です。 – Makoto

+0

@Makotoこれは本当にエラーを出すでしょう:D、単なる例でした。今すぐ変更しました。 – n247s

答えて

2

これは何も問題はありません。それは実際にはかなり一般的な方法です。

+0

申し訳ありません、ありがとうございます。私は確かにこれは一日良いソリューションがあることを願っています。 – n247s

1

これは非常に一般的な方法です。例:

Enum<E extends Enum<E>> 

BaseStream<T, S extends BaseStream<T, S>> 

ただし、制限事項に注意してください。主なものは、継承でうまくいっていないということです。

あなたがインターフェイス

interface Animal<A extends Animal<A>> 

を持っている場合たとえば、あなたはこれが正常に動作します。この

class Duck implements Animal<Duck> 

などの具体的な実装を書くことを決めるかもしれませんが、後であなたがDuckを拡張することにした場合これを書くことはできません:

class MallardDuck extends Duck implements Animal<MallardDuck> 

これは、DuckがすでにAnimal<Duck>を実装しているため、MallardDuckAnimal<MallardDuck>を実装することはできませんので、2つの異なるタイプのパラメータで同じ汎用インターフェイスを実装できないということです。

このパターンを使用する場合は、インタフェースの実装方法から非常に慎重に考えてください。それはEnumで動作します。言語で拡張することができないためですが、あまりにも多く使用するとこのパターンは完全な混乱を招く可能性があります。

+0

これは論理的です。通常のインターフェースでも同様ですが?それは基本的にgenericTypesを隠しています。メソッドには戻り値の型が 'Duck'(この場合)であるため、サブクラスはその戻り値の型をもう変更できません。それは通常のインターフェースと変わりありませんが。とにかく指摘してくれてありがとう。 – n247s

関連する問題