質問

Javaでミックスインまたは特性をエミュレートする方法はありますか?基本的に、複数のクラスに共通のビジネスロジックを追加できるように、複数の継承を行う方法が必要です

役に立ちましたか?

解決

すべてのビジネスロジックを新しいクラス BusinessLogic にカプセル化し、 BusinessLogic を必要とする各クラスにクラスを呼び出します。 BusinessLogic を呼び出すクラスに単一ルートの階層が必要な場合は、インターフェースも作成する必要があります( BusinessLogicInterface ?)

擬似コード内:

interface BusinessLogicInterace
{
    void method1();
    void method2();
}

class BusinessLogic implements BusinessLogicInterface
{
    void method1() { ... }
    void method2() { ... }
}

class User 
    extends OtherClass 
    implements BusinessLogicInterface
{
    BusinessLogic logic = new BusinessLogic();

    @Override
    void method1() { logic.method1(); }

    @Override
    void method2() { logic.method2(); }
}

これは、多重継承の欠如を回避するための最も美しい実装ではなく、インターフェイスに多くのメソッドがある場合、非常に面倒になります。おそらく、ミックスインが不要になるようにコードを再設計してみてください。

他のヒント

あなたがやりたいことではありません。 効果的なJava では、「継承よりも合成を優先する」ことをお勧めします。つまり、共通ロジックを他のクラスに移動して委任します。これは、Javaの多重継承の欠如を回避する方法です。

今日、オブジェクト純粋主義者はあなたの中で動揺していますか?

小さな複合指向プログラミングでできると思いますか

その後、あなたは Apache Polygene (以前のQi4JまたはZest)を探しています;)

多重継承に対するJavaの答えは、複数のインターフェースを実装する能力です。もちろん、これはメソッド宣言を取得することを意味しますが、ロジックは取得しません。

構成によってミックスインをエミュレートできます。Javaクラスは、一般的なビジネスロジックを実行する他のクラスを表すメンバー変数を定義できます。

Javaクラスの設計において、アーキテクチャの設計を妨げるC ++スタイルの多重継承の欠如を発見していません。あなたがしたいことを達成する方法を見つけるでしょう。

QI4Jでは、ミックスインを使用できます

インターフェイスがネストされたクラス(自動的にパブリックスタティック)を許可するという事実を活用して、インターフェイス自体の内部にカプセル化されたインターフェイスメソッドの既定の実装を維持できます。つまりAlex BのサンプルのBusinessLogicクラスをインターフェイス内に移動します。

これは、Scalaがここで説明する特性のJVMコードを生成する方法に似ています Scala特性はどのようにJavaバイトコードにコンパイルされますか?

これを行うと、例は次のようになります。

interface BusinessLogicInterface {
    void method0();

    class DefaultImpl {
        private DefaultImpl() {
        }

        public static void method1(BusinessLogicInterface self) { ... }
        public static void method2(BusinessLogicInterface self) { ... }
    }

    void method1();
    void method2();
}

class User extends OtherClass implements BusinessLogicInterface {
    @Override
    void method0() { ... }

    @Override
    void method1() { BusinessLogic.defaultImpl.method1(this); }

    @Override
    void method2() { BusinessLogic.defaultImpl.method2(this); }
}

インターフェイスタイプのオブジェクトを" self"として渡すことに注意してください。パラメータ。これは、ビジネスロジックが他の抽象メソッド(method0)を使用できることを意味します。これは、すべて互いに直交する抽象メソッドとユーティリティ「拡張」で特性を作成するのに非常に役立ちます。これらの直交メソッドの観点から実装できるメソッド。

欠点は、各インターフェイスが定型的な委任コードをコピー/貼り付けする必要があることです。この欠点のないJavaでよく使用される別のパターン(ただし、まとまりが少なく、メソッドを呼び出すオブジェクト指向の方法が少ない)は、静的メソッドを含むインターフェイスとして複数の名前を持つクラスを作成することです。これは、コレクションユーティリティクラスで使用されます。 / p>

CGLib / javassitを使用したJavaでの簡単なmixin / traitsサポートの実装は非常に簡単です。 たとえば、こちらをご覧ください小さな例。 より完全ですぐに使用できるソリューションが見つかるかもしれません:こちら

Java-8では、デフォルトのインターフェースメソッドが追加されました。これと、Javaのインターフェースの多重継承により、何らかのミックスインが可能になります。明らかに、インターフェイスは独立して動作する必要があります。したがって、重大な制限があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top