2009-08-05 14 views
0

Ich habe drei Klassen (Klasse A, Klasse B und Klasse C).Java Erweiterung/Abstraktion/Implementierung Frage

Klasse A ruft eine Instanz von B auf und startet start().

Klasse B erweitert Thread, wenn also start() aufgerufen wird, wird alles in der run() -Methode ausgeführt.

Im run() Thread gibt es eine Instanz der Klasse C.

Gibt es trotzdem eine Methode in der Klasse C zu ermöglichen, eine Methode in der Klasse A zu nennen, ohne eine neue Instanz der Klasse A instanziieren?

Da ich Klasse A nicht auf Klasse B erweitern kann (weil "Thread" bereits erweitert ist), weiß ich nicht, wie ich das machen würde.

Entschuldigung für die Undeutlichkeit, aber mein Projekt verfügt über viel zu viel Code und ist viel zu kompliziert, um ein direktes Codebeispiel zu liefern.

Danke!

Antwort

1

So haben Sie

class A { 
void run() 
{ 
    new B().start(); 
} 
} 

class B extends Thread { 
    public void run(){ 
    C c = new C(); 
    c.do something with A .. } 
} 

Sie den Anrufer übergeben kann, was hässlich könnte, wie Sie ein den ganzen Weg hinunter zu C durch B bestehen:

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).. 
    } 
} 

oder vereinfachen, vor allem, wenn B und C keinen anderen Grund dafür haben:

class A { 
public void run() 
{ 
    this.do something() ... 
} 
} 
+0

Großartig, danke! Eine Menge guter Ratschläge, aber zeitlich begrenzt war dies die einfachste Lösung für etwas schlechtes Design und zu kompliziert. – Monster

1

Der beste Weg könnte sein, dass der Start von Klasse B überladen wird, um einen Parameter zu übernehmen (A, oder besser, eine Schnittstelle, die von A implementiert wird). Dann kann B entweder speichern, dass für den Abruf durch C (wenn es eine innere Klasse ist), oder gibt sie an C Konstruktor ...

EDIT:

Obwohl als der Kommentator zwingenden erwähnte der Konstruktor funktionieren würde, es doesn‘ t passen die Parameter der Frage, die so formuliert wurde, dass B bereits existierte, so mein Vorschlag, den Start() so zu überlasten ist:

b.start(A aParam) { 
    a=aParam; 
    start(); 
} 

diese Version Gewinde ist jedoch nicht sicher. Bs Konstruktor funktioniert, wenn B jedes Mal instanziiert wird, oder wenn C beim Start von b instanziiert wird, dann könnte es an Cs Konstruktor übergeben werden, wenn es instanziiert wird.

Übrigens ist das Erweitern Thread aus vielen Gründen im Allgemeinen nicht so gut wie das Ausführen ausführbar.

+0

Ich bin sicher, du meintest "Konstruktor der Klasse B". Overriding Thread.start() wird nicht viel Gutes tun. – ChssPly76

1

Dies ist eine kreisförmige Abhängigkeit, eine sehr schlechte Sache in OOP in meiner (bescheidenen) Meinung.

Sie Ihren Code Refactoring muss

0

Eine andere Möglichkeit, eine gemeinsame Klasse für A und C zur Verfügung zu stellen Thread Verhalten in Java zu verwenden, ist Runnable zu implementieren. Vorstellbar könnte man A erweitern und implementieren Runnable und verwendet:

Thread t = new Thread(b) 
t.start(); 

aus einer OOP Sicht hässlich scheint, aber es könnte möglicherweise Sinn unter bestimmten Umständen machen. Die anderen beiden Antworten scheinen ein wenig vernünftiger zu sein, haben aber gedacht, dass dies in Betracht gezogen werden könnte.