Java: Как получить доступ к методу родительского класса на два уровня ниже? - PullRequest
27 голосов
/ 25 июня 2010

У меня есть класс, который расширяет класс, который мне нужно переопределить, но мне нужно вызвать родительский класс этого класса.так как я не могу вызвать super, так как это будет выполнять непосредственный родитель, каков наилучший способ получить родительский класс моего родительского класса?

Я уверен, что это базовый вопрос, но я уже давноделал какие-то 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 */ }
}

Ответы [ 6 ]

30 голосов
/ 25 июня 2010

Вы этого не делаете: это нарушает инкапсуляцию.

Можно сказать: «Нет, я не хочу своего собственного поведения - я хочу поведение моих родителей», потому что предполагается, что вы будете делать толькопоэтому, когда он правильно поддерживает ваше собственное состояние.

Однако вы не можете обойти поведение своего родителя - это помешает ему обеспечить собственную согласованность.Если родительский класс хочет, чтобы позволял вам вызывать метод дедушки напрямую, он может представить это через отдельный метод ... но это до родительского класса.

9 голосов
/ 25 июня 2010

Вы не можете, потому что это было переопределено B. В C. нет экземпляра A.

Дело в том, что вы хотите вызвать метод класса A, но из какого экземпляра? Вы создали экземпляр C, который является классом с парой собственных и унаследованных методов из B. Если B переопределяет метод A, вы не можете получить к нему доступ из C, поскольку сам метод принадлежит C (это не метод B, он был унаследован и теперь находится в C)

Возможные обходные пути:

B не отменяет myMethod()

C получает экземпляр A и сохраняет его как свойство класса.

myMethod() в A является статическим, и вы используете A.myMethod() (я не рекомендую это)

6 голосов
/ 25 июня 2010

То, что вы спрашиваете, является плохой практикой. То, что вы говорите, это то, что C - это не B, а A. Что вам нужно сделать, так это чтобы C наследовал от A. Тогда вы можете назвать super.

Если нет, то это единственный способ ...

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;
}
1 голос
/ 25 июня 2010

Кроме того, что ответил pakore, вы также можете связать super.myMethod() звонки, если это работает для вас. Вы будете звонить myMethod() из А из myMethod() в Б.

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

В конечном итоге вы будете вызывать myMethod из A, но косвенно ... Если это работает для вас.

0 голосов
/ 28 декабря 2017

Что я делаю для этого случая:

Создайте объект класса A внутри класса C и получите доступ к классу A там.Этот пример, который разъясняет более подробную информацию:

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();

 }

}

Вывод этого примера:

A class a: 30
B class a: 20
C class a: 10
0 голосов
/ 25 июня 2010

Вы не можете вызвать метод А напрямую. В тех немногих случаях, которые я затронул, решением было добавить метод в A, чтобы раскрыть его реализацию. Э.Г.

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();
   }
}

Схема отделяет открытый интерфейс (doMyMethod) от реализации (doAMyMethod). Наследование зависит от деталей реализации, и это не так уж плохо, но я постараюсь избежать его, если это возможно, так как это создает тесную связь между реализацией в A и C.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...