javaでミックスインまたは特性をエミュレートする方法はありますか? 基本的に、複数のクラスに共通のビジネス ロジックを追加できるように、複数の継承を行う方法が必要です。
8 に答える
あなたがやりたい方法ではありません。効果的な Javaでは、「継承よりも構成を優先する」ことをお勧めします。つまり、共通ロジックを他のクラスに移動してデリゲートします。これは、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(); }
}
これは、多重継承の欠如を回避するための最も美しい実装ではなく、インターフェイスに多くのメソッドがある場合は非常に扱いにくくなります。ほとんどの場合、ミックスインを必要としないようにコードを再設計する必要があります。
今日、オブジェクト純粋主義者はあなたの中で動揺していますか?
少しの複合指向プログラミングでできると思いますか?
次に、あなたはApache Polygene (以前の Qi4J または Zest)を探しています ;)
QI4J ではミックスインを使用できます
多重継承に対する Java の答えは、複数のインターフェースを実装する機能です。もちろん、これはメソッド宣言を取得することを意味しますが、ロジックは取得しません。
コンポジションによって mixin をエミュレートすることができます。Java クラスは、いくつかの一般的なビジネス ロジックを実行する他のクラスを表すメンバー変数を定義できます。
Java クラスの設計において、C++ スタイルの多重継承の欠如が私のアーキテクチャーの設計を阻害することはありませんでした。やりたいことを実現する方法が見つかります。
インターフェイスがネストされたクラス (自動的に 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 つのパターン (ただし、凝集度が低く、メソッドを呼び出すオブジェクト指向の方法が少ない) は、静的メソッドを含むインターフェイスとして複数形の名前を持つクラスを作成することです。これは、コレクション ユーティリティ クラスで使用されます。