Java拡張機能/抽象化/実装の質問
-
22-07-2019 - |
質問
3つのクラス(クラスA、クラスB、およびクラスC)があります。
クラスAはBのインスタンスを呼び出し、start()を実行します。
クラスBはThreadを拡張するため、start()が呼び出されると、run()メソッドのすべてが実行されます。
run()スレッドには、クラスCのインスタンスがあります。
とにかく、クラスAの新しいインスタンスをインスタンス化せずに、クラスCのメソッドがクラスAのメソッドを呼び出すことを許可しますか?
クラスAをクラスBに拡張できないため(" Thread"は既に拡張されているため)、これをどのように実行するかわかりません。
あいまいですが、私のプロジェクトは非常に多くのコードを備えており、直接的なコード例を提供するには複雑すぎます。
ありがとう!
解決
つまり、
class A {
void run()
{
new B().start();
}
}
class B extends Thread {
public void run(){
C c = new C();
c.do something with A .. }
}
AをBを介してCに渡す必要があるため、呼び出し元を渡すことができます。
class A {
void run()
{
new B(this).start();
}
}
class B extends Thread {
public void run(A a){
C c = new C();
c.do something(a)..
}
}
特にBとCに他に理由がない場合:または単純化:
class A {
public void run()
{
this.do something() ...
}
}
他のヒント
これは循環依存関係であり、私の(控えめな)意見ではOOPで非常に悪いことです。
AおよびCに共通のクラスを提供するには、コードをリファクタリングする必要があります。
最善の方法は、クラスBのオーバーロードを開始してパラメーターを取得することです(A、またはそれよりも優れているが、Aによって実装されるインターフェース)。次に、Bは、Cによる取得のために(内部クラスの場合)保存するか、Cのコンストラクターに渡すことができます...
編集:
コメンターがコンストラクターのオーバーライドを機能させると述べたように、Bが既に存在するように表現された質問のパラメーターには適合しないため、私の提案はstart()を次のようにオーバーロードすることです:
b.start(A aParam) {
a=aParam;
start();
}
ただし、このバージョンはスレッドセーフではありません。 Bが実際に毎回インスタンス化される場合、またはBの開始時にCがインスタンス化される場合、Bのコンストラクターは機能します。インスタンス化されると、Cのコンストラクターに渡されます。
ところで、スレッドを拡張することは、いくつかの理由でrunnableを実装するほど一般的には良くありません。
Javaでスレッドの動作を利用する別の方法は、Runnableを実装することです。おそらくAを拡張し、Runnableを実装し、次を使用できます:
Thread t = new Thread( b )
t.start();
OOPの観点から見るといように見えますが、特定の状況下では理にかなっています。他の2つの答えはもう少し理にかなっているように見えますが、これを検討できると考えました。