Question

J'ai trois classes (classe A, classe B et classe C).

La classe A appelle une instance de B et exécute start ().

La classe B étend Thread. Ainsi, lorsque start () est appelée, tout ce qui se trouve dans la méthode run () est exécuté.

Dans le thread run (), il existe une instance de la classe C.

Est-il possible d'autoriser une méthode de la classe C à appeler une méthode de la classe A sans instancier une nouvelle instance de la classe A?

Etant donné que je ne peux pas étendre la classe A à la classe B (car "le thread" est déjà étendu), je ne sais pas comment procéder.

Désolé d'être vague, mais mon projet contient beaucoup trop de code et est bien trop compliqué pour fournir un exemple de code direct.

Merci!

Était-ce utile?

La solution

Donc vous avez

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

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

Vous pouvez faire passer l'appelant, ce qui peut devenir moche, car vous devez passer de A tout en bas, de C à 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).. 
  }
}

ou simplifier, surtout si B et C n’ont aucune autre raison d’être:

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

Autres conseils

C’est une dépendance circulaire, une très mauvaise chose en POO à mon avis (modeste).

Vous devez refactoriser votre code pour fournir une classe commune à A et C.

Le meilleur moyen pourrait être que les classes B commencent à être surchargées pour prendre un paramètre (A, ou mieux encore, une interface implémentée par A). Ensuite, B peut soit le stocker pour le récupérer par C (s’il s’agit d’une classe interne), soit le transmettre au constructeur de C ...

EDIT:

Bien que le commentateur ait mentionné que le remplacement du constructeur fonctionnerait, cela ne correspond pas aux paramètres de la question formulée de telle manière que B existait déjà. Je suggère donc de surcharger le début () de la manière suivante:

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

Cette version n'est cependant PAS thread-safe. Le constructeur de B fonctionne si B est instancié à chaque fois, ou si C est instancié au démarrage de b, il peut alors être transmis au constructeur de C lorsqu'il est instancié.

Soit dit en passant, étendre le thread n’est généralement pas aussi efficace que de lancer runnable pour plusieurs raisons.

Une autre façon d'utiliser le comportement des threads en Java consiste à implémenter Runnable. Vous pouvez éventuellement étendre A, implémenter Runnable et utiliser:

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

Cela semble moche du point de vue de la programmation orientée objet, mais cela pourrait avoir un sens dans certaines circonstances. Les deux autres réponses semblent un peu plus sensées, mais ont figuré que cela pourrait être envisagé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top