J'ai 2 classes, et j'ai créé une classe (classe A) instancie un objet de classe B.
J'ai une méthode en Classe B que je veux appeler une méthode en Classe A.
Je travaille sur un projet plus vaste pour pratiquer Java, donc je simplifie les choses ici. p >
// Classe A:
public class ClassB {
public void incrementNumberInA() {
// My desire: Call Class A's incrementNumber method
// What should I put here?
}
// Classe B:
public class ClassA {
private int number;
private ClassB instanceOfB = new ClassB();
public ClassA {
number = 0;
}
public void incrementNumber {
number++;
}
public void incrementNumberLongWay {
instanceOfB.incrementNumberInA()
}
}
}
Comment m'assurer que incrementNumberLongWay fonctionne? La classe A a été instanciée, et sa méthode incrementNumberLongWay est appelée, donc cela devrait appeler la méthode de ClassB incrementNumberInA
Je sais que cela semble extrêmement compliqué, mais la raison pour laquelle je fais cela, c'est parce que dans mon programme je ' Je n'incrémente pas les nombres, mais fais plutôt de la logique dans la classe B, et ne veux affecter la classe A que dans certains cas.
5 Réponses :
C'est probablement une mauvaise idée en général d'avoir une dépendance circulaire de cette manière. Une approche pour briser le cycle serait d'avoir une troisième classe (classC?) Qui implémente la logique d'incrémentation (ou quel que soit votre équivalent dans le monde réel), et d'avoir des instances classA et classB pour chaque classe de référence. De cette façon, il n'y a aucun cas où deux classes se connaissent.
Vous ne pouvez pas faire cela avec le code fourni. Les relations sont à sens unique par défaut. B ne connaît pas A et ne peut donc pas y accéder.
Ce que vous pouvez faire est de passer une référence de A à B dans son processus de construction, puis d'accéder à A via cette référence.
La classe B ne sait rien de la classe. Donc, vous ne pouviez pas le faire. La mauvaise décision est
public class ClassB {
public void incrementNumberInA(ClassA cl) {
cl.incrementNumber();
}
}
et dans
public void incrementNumberLongWay() {
instanceOfB.incrementNumberInA(this);
}
Vous ne pouvez pas appeler des méthodes de la classe A depuis la classe B car la classe B n'a pas de référence à un objet de la classe a. Vous pouvez, cependant, passer l'état numérique actuel de la classe A à la classe B en tant que paramètre, et renvoyer une valeur de la classe B que la classe A peut ensuite obtenir et utiliser.
Par exemple:
public class A {
private int number;
public A(int number) {
this.number = number;
}
public void incrementNumber(boolean largeIncrement) {
if(largeIncrement) {
B bInstance = new this.B();
number = bInstance.incrementNumberLongWay(number);
}
else {
number++;
}
}
private class B {
private B() {
// if some initialization is needed...
}
public int incrementNumberLongWay(int num) {
num += 1000;
return num;
}
}
}
Une solution serait de passer une méthode de A comme rappel.
Par exemple:
public class ClassA {
private int number;
private ClassB instanceOfB = new ClassB();
public ClassA {
number = 0;
}
public void incrementNumber {
number++;
}
public void incrementNumberLongWay {
instanceOfB.incrementNumberInA(this::increment);
// alternatively
// instanceOfB.incrementNumberInA(() -> incrementNumber());
}
}
public class ClassB {
public void incrementNumberInA(Runnable callbackMethod) {
callbackMethod.run();
}
}
Cela supprime la dépendance de B sur A et permet à mécanisme de rappel.
Cependant, pour un scénario aussi simple, cette approche n'est pas conseillée.
Désolé, il a fallu plus d'un an pour accepter une réponse. C'était ma deuxième question sur SO. :RÉ
Pourquoi ne renverriez-vous pas simplement une valeur de l'instance de B dans incrementNumberLongWay () et incrémenter la valeur en fonction du résultat renvoyé?
Je ne fais pas cela parce que la classe B renvoie en fait quelque chose d'autre, ce qui est beaucoup plus important. Je pensais empaqueter à la fois la variable la plus importante et le nombre incrémenté, mais je suis plus habitué à python et à utiliser des tuples.