17

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

4

8 に答える 8

17

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

于 2008-11-04T19:45:31.920 に答える
12

すべてのビジネス ロジックを新しいクラスにカプセル化し、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(); }
}

これは、多重継承の欠如を回避するための最も美しい実装ではなく、インターフェイスに多くのメソッドがある場合は非常に扱いにくくなります。ほとんどの場合、ミックスインを必要としないようにコードを再設計する必要があります。

于 2008-11-04T19:47:26.940 に答える
4

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

少しの複合指向プログラミングでできると思いますか?

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

于 2008-11-04T20:26:35.287 に答える
3

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

于 2010-10-14T17:48:15.070 に答える
3

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

コンポジションによって mixin をエミュレートすることができます。Java クラスは、いくつかの一般的なビジネス ロジックを実行する他のクラスを表すメンバー変数を定義できます。

Java クラスの設計において、C++ スタイルの多重継承の欠如が私のアーキテクチャーの設計を阻害することはありませんでした。やりたいことを実現する方法が見つかります。

于 2008-11-04T19:44:14.263 に答える
2

インターフェイスがネストされたクラス (自動的に public static) を許可するという事実を利用して、インターフェイス自体にカプセル化されたインターフェイス メソッドのデフォルトの実装を保持できます。つまり、Alex B の例の BusinessLogic クラスをインターフェイス内に移動します。

これは、ここで説明されているように、Scala が特性の JVM コードを生成する方法に似ています。

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

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 でよく使用されるもう 1 つのパターン (ただし、凝集度が低く、メソッドを呼び出すオブジェクト指向の方法が少ない) は、静的メソッドを含むインターフェイスとして複数形の名前を持つクラスを作成することです。これは、コレクション ユーティリティ クラスで使用されます。

于 2013-05-02T11:49:59.517 に答える
0

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

于 2011-10-21T11:18:23.610 に答える