5

流暢なアプローチを採用すると、次のシナリオが考えられます。

public class Foo<T extends a>{

    public Foo<T> someMethod(){
          System.out.println("foo");
          return this;
    }

}


public class Bar<T extends b> extends Foo<T> {

         public Bar<T> barMethod(){

            System.out.println("bar");
            return this;
         }

}


public class a{}
public class b extends a{}

流暢なインターフェイスの強みは、メソッド呼び出しを連鎖できることですが、Bar は someMethod() を継承していますが、戻り値の型は Bar ではなく Foo であり、次の連鎖を壊してしまいます:

new Bar<b>().someMethod().barMethod();

1 つの答えは、Bar に追加のメソッドがあるように、継承されたすべてのメソッドに @Overrides を追加することです。

 @Override
 public Bar<T> someMethod(){
          System.out.println("foo");
          return this;
    }

しかし、大規模なクラスや拡張されたクラス階層では、これは確実に冗長性の混乱を証明する可能性があります?! 流暢なメソッドに与える適切な戻り値の型はありますか?それにより、それを継承するすべてのクラスが特定の型のオブジェクトを返します (キャストなしでメソッドを連鎖できるようにするため)。

私は試した:

        public <U extends Foo<T>> U someMethod(){
          System.out.println("foo");
          return this;
    }

残念ながら、役に立ちません。この問題に対するシンプルでエレガントな解決策を誰かが知っていることを願っています。プロジェクトは大規模であるため、可能であれば保守と拡張が可能である必要があります。

このシナリオで提供できるヘルプに感謝します。

4

2 に答える 2

5

チェックされていないキャストを気にしない場合は、次のようにすることができます。

public class Foo<T, F extends Foo<T, F>> {
  public F someMethod() {
    System.out.println("foo");
    return (F) this; // <--- That's the unchecked cast! Tucked safely away.
  }
  public static void main(String[] args) {
    new Bar<String>().someMethod().barMethod();
  }
}

class Bar<T> extends Foo<T, Bar<T>> {
  public Bar<T> barMethod() {
    System.out.println("bar");
    return this;
  }
}

個人的には、プロジェクト全体で未チェックのキャスト警告をグローバルに無効にしています。

于 2012-10-29T09:29:42.153 に答える
1

できることは、メソッド抽象を定義することです。これで、型barMethodで呼び出すことができます。Foo

public abstract class Foo<T extends a> {

    public Foo<T> someMethod() {
        System.out.println("foo");
        return this;
    }

    public abstract Foo<T> barMethod();
}

簡単に電話できるようになりました

new Bar<b>().someMethod().barMethod();
于 2012-10-29T09:21:57.217 に答える