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