Domanda

Ho tre classi (classe A, classe B e classe C).

La classe A chiama un'istanza di B ed esegue start ().

La classe B estende Thread, quindi quando viene chiamato start (), viene eseguito qualsiasi cosa nel metodo run ().

Nel thread run (), esiste un'istanza di classe C.

Esiste un modo per consentire a un metodo in Classe C di chiamare un metodo in Classe A, senza creare un'istanza di una nuova istanza di Classe A?

Dal momento che non posso estendere la classe A alla classe B (perché "Thread" è già esteso), non so come farei per farlo.

Ci scusiamo per essere vago, ma il mio progetto presenta troppi codici ed è troppo complicato per fornire un esempio di codice diretto.

Grazie!

È stato utile?

Soluzione

Quindi hai

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

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

Puoi passare il chiamante, che potrebbe diventare brutto, dato che devi passare da A fino a C attraverso B:

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

o semplificare, specialmente se B e C non hanno altri motivi per essere:

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

Altri suggerimenti

questa è una dipendenza circolare, una cosa molto brutta in OOP secondo la mia (modesta) opinione.

Devi refactificare il tuo codice per fornire una classe comune per A e C.

Il modo migliore potrebbe essere che l'inizio della classe B sia sovraccaricato per prendere un parametro (A, o meglio ancora, un'interfaccia implementata da A). Quindi B può memorizzarlo per il recupero da parte di C (se si tratta di una classe interna) o passarlo al costruttore di C ...

EDIT:

Sebbene il commentatore che ha menzionato l'override del costruttore abbia funzionato, non si adatta ai parametri della domanda formulata in modo tale che B esistesse già, quindi il mio suggerimento è di sovraccaricare start () in questo modo:

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

Questa versione NON è comunque thread-safe. Il costruttore di B funziona se B viene effettivamente istanziato ogni volta, o se C viene istanziato all'avvio di b, potrebbe essere passato al costruttore di C mentre viene istanziato.

A proposito, l'estensione del thread non è generalmente buona come l'implementazione eseguibile per diversi motivi.

Un altro modo per utilizzare il comportamento dei thread in Java è implementare Runnable. Concepibilmente si potrebbe estendere A, implementare Runnable e usare:

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

Sembra brutto da un punto di vista OOP, ma in determinate circostanze potrebbe avere senso. Le altre due risposte sembrano un po 'più sensate, ma hanno pensato che questo potesse essere preso in considerazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top