web-dev-qa-db-fra.com

Java: Comment accéder à une méthode de classe parent à deux niveaux?

J'ai une classe qui étend une classe que j'ai besoin de dépasser, mais je dois appeler la classe parente de cette classe. puisque je ne peux pas appeler super puisque cela exécutera le parent direct, quel est le meilleur moyen d'obtenir le parent de ma classe parente?

Je suis sûr que c’est une question fondamentale, mais cela fait longtemps que je n’utilise pas de Java.

class A
{
 public void myMethod()
 { /* ... */ }
}

class B extends A
{
 public void myMethod()
 { /* Another code */ }
}

class C extends B
{
 I need to call Class A here
 { /* Another code */ }
}
27
dan.codes

Vous ne le faites pas: cela viole l'encapsulation.

C'est bien de dire: "Non, je ne veux pas de mon propre comportement - je veux du comportement de mes parents" parce qu'il est supposé que vous ne le ferez que s'il maintient votre propre état correctement.

Cependant, vous ne pouvez pas contourner le comportement de votre parent - cela l'empêcherait d'appliquer sa propre cohérence. Si la classe parente veut pour vous permettre d'appeler directement la méthode des grands-parents, elle peut l'exposer via une méthode séparée ... mais cela dépend de la classe parente.

29
Jon Skeet

Vous ne pouvez pas parce qu'il a été remplacé par B. Il n'y a pas d'instance de A dans C.

Le fait est que vous voulez appeler une méthode de la classe A, mais à partir de quelle instance? Vous avez instancié C, qui est une classe avec quelques méthodes propres et héritées de B. Si B substitue une méthode de A, vous ne pouvez pas y accéder depuis C, car la méthode elle-même appartient à C (n'est pas une méthode. de B, il a été hérité et maintenant il est en C)

Solutions possibles:

B ne remplace pas myMethod()

C reçoit une instance de A et l’enregistre en tant que propriété de classe.

myMethod() en A est statique et vous utilisez A.myMethod() (je ne le recommande pas)

9
pakore

Ce que vous demandez est une mauvaise pratique. Ce que vous dites, c'est que C n'est pas un B, mais un A. Ce que vous devez faire, c'est que C hérite de A. Vous pouvez alors appeler super.

Si ce n'est pas le seul moyen ...

public String A()
{
String s = "hello";
return s;
}

public String B()
{
String str = super.A();
return str;
}

public String C()
{
String s = super.B();
return s;
}
6
Romain Hippeau

Outre ce que pakore a répondu, vous pouvez également chaîner des appels super.myMethod() si cela vous convient. Vous appelez myMethod() à partir de A à partir de myMethod() dans B.

class A {
   public void myMethod() {
     ....
   }
}

class B extends A {
   public void myMethod() {
     ....
     super.myMethod();
     ....
   }
}

class C extends B {
  public void myMethod() {
    ....
    super.myMethod(); //calls B who calls A
    ....
  }
}

Vous appellerez éventuellement myMethod de A, mais indirectement ... Si cela vous convient.

1
user159088

Vous ne pouvez pas appeler la méthode de A directement. Dans les quelques cas où j'ai trouvé cela, la solution consistait à ajouter une méthode dans A pour exposer sa mise en œuvre. Par exemple.

class A
{
   public myMethod() {
        doAMyMethod();
   }

   void doAMyMethod() {
      // what A want's on doMyMethod, but now it's available
      // as a separately identifiable method
   }
}

class C extends B
{
   public void someStuff() {
      this.doAMyMethod();
   }
}

Le schéma sépare l'interface publique (doMyMethod) de l'implémentation (doAMyMethod). L'héritage dépend des détails de l'implémentation, donc ce n'est pas si grave, mais j'essaierais de l'éviter si possible car cela crée un couplage étroit entre l'implémentation en A et en C.

0
mdma

Ce que je fais pour ce cas est:

Créez l'objet de classe A dans la classe C et accédez à la classe A. Cet exemple qui clarifie plus de détails:

class A{
int a;
}
class B extends A{
int a;
}
class C extends B{
int a; 
A obj = new A();
public void setData(int p,int q, int r) {

 this.a = p; //  points to it's own class
 super.a = q;// points to one up level class i.e in this case class B
 obj.a = r; // obj points the class A
}
 public void getData() {
    System.out.println("A class a: "+ obj.a);
    System.out.println("B class a: "+ super.a);
    System.out.println("C class a: "+this.a);
 }
}

public class MultiLevelInheritanceSuper {

 public static void main(String args[]){
    C2 obj = new C2();
    obj.setData(10, 20, 30);
    obj.getData();

 }

}

La sortie de cet exemple est:

A class a: 30
B class a: 20
C class a: 10
0
susan097