12

私は次のようなクラスを持っています:

MyClass extends MyAbstractClass implement myInterface1, myInterface2,...

追加のフィールドを持つ新しいクラスを作成する必要があります。

MyType1 field1;
MyType2 field2;
.......

MyClassを次のようにラップする新しいクラスを正しく作成するようです。

MyWrapClass {
 MyClass myClass=new MyClass(...);
 MyType1 field1;
 MyType2 field2;
 .....

ただし、MyWrapClassはタイプmyInterface1またはmyInterface2として使用されます。

したがって、質問は次のとおりです。MyWrapClassのインターフェイスmyInterface1、myInterface2に必要なすべてのメソッドを宣言する必要がありますか?または別の方法が存在しますか?ありがとう。

4

5 に答える 5

16

基本的に2つの方法があります。1つ目は、基本クラスを拡張することです。

public class MySubClass extends MyClass {
     private MyType1 field1;
     private MyType2 field2;
....

2番目のオプションは、構成を使用することです。

public class MySubClass implements myInterface1, myInterface2 {
      private MyClass delegate;
      private MyType1 field1;
      private MyType2 field2;

      // for all methods in myInterface1, myInterface2
      public SomeType method1() {
         return delegate.method1();
      }
      ... 
}

2番目のオプションは、多くのJavaGurusによって推奨されています。

JoshBlochの本EffectiveJava2nd Edition

  • 項目16:継承よりも構成を優先する
  • 項目17:相続のための設計と文書化、または相続を禁止する

優れたオブジェクト指向設計は、既存のクラスを自由に拡張することではありません。あなたの最初の本能は、代わりに作曲することです。

http://en.wikipedia.org/wiki/Composition_over_inheritanceも参照してください

継承を介した構成により、ビジネスドメインクラスの初期設計が簡素化され、長期的にはより安定したビジネスドメインが提供されます。継承に対するその利点は、子孫クラスの階層で説明できるよりも、利益をより完全に分離できることです。さらに、継承モデルは、問題のドメイン内の情報を理解するためにビジネスドメインクラスの定義中に考案されることが多く、必ずしもさまざまなシステムオブジェクトの真の関係を反映しているわけではありません。

PS:構成用のコードの自動生成は、最新のIDEの一部でサポートされています

于 2012-04-04T16:10:43.810 に答える
3

ラップしないでください。サブクラスだけです。

class MySubClass extends MyClass {
    MyType1 field1;
    MyType2 field2;
    ...
于 2012-04-04T15:50:44.070 に答える
2

MyClassを拡張できないと仮定すると、MyWrapClassを使用してMyClassのように使用する方法は他にありません。たとえば、実際のマップをラップするためにMapを実装する必要があることがありました。それは多くの機能を持っており、あなたが使用しようとしているそれらのすべてを実装する必要があります。ここには少し余裕があります。作成していない関数に渡す予定がない場合は、必要なすべてのメソッドを追加して、必要なメソッドだけを実装できます。多くの場合、そうではありません。

または、ラッパーを呼び出すインターフェイスのすべてのメソッドを実装するダミークラスを作成することもできます。次に、このクラスを独自の実装でオーバーライドして、毎回すべてのメソッドを実装しなくてもラッパークラスをリサイクルできるようにします。

于 2012-04-04T15:58:51.183 に答える
2

プロキシが解決する可能性のある問題のように聞こえます:http: //docs.oracle.com/javase/1.5.0/docs/guide/reflection/proxy.html

注意してください、それは遅いです(反射を使用します)

于 2012-04-04T16:03:09.867 に答える
2

MyClassを拡張できず、MyWrapClassをタイプmyInterface1またはmyInterface2として使用できるようにしたいとします。次のことができます。

MyWrapClass implement myInterface1, myInterface2,...{
   MyClass myClass=new MyClass(...);
   MyType1 field1;
   MyType2 field2;

   methodInInterface1 () {
      myClass.methodInInterface1 ()
   }

   ....

myInterface1およびmyInterface2のすべてのメソッド実装をMyClassに委任します。これは作曲と呼ばれていると思います。

于 2012-04-04T16:13:27.680 に答える