2015-01-21 25 views
5

Jako przykład twisterki mózgu, profesor dał nam następujące ćwiczenie, aby dowiedzieć się o dziedziczeniu. Musieliśmy obliczyć wyjście.Wywołanie super metody z poziomu super klasy

//java 
public class A { 
    public void f() { 
     System.out.println("A -> f()"); 
     x = x + 4; 
     if (x < 15) this.f(); //the f-call 
    } 
    public int x = 5; 
} 

public class B extends A { 
    @Override 
    public void f() { 
     System.out.println("B -> f()"); 
     x = x + 3; 
     super.f(); 
    } 
} 

public class Main { 
    public static void 
    main(String[] args) { 
     A a = new B(); 

     System.out.println("a.f()"); 
     a.f(); 
     System.out.println(a.x); 
    } 
} 

wyjście jest, jak się spodziewano,

  • AF()
  • B -> F()
  • A -> C()
  • B -> F ()
  • A -> C()

Jednak teraz się zastanawiałem. Czy istnieje sposób na wykonanie f-call w wywołaniu f metody w A, nawet gdy używam go z obiektu B, podobnie do sposobu, w jaki wywołuję f z A w B, używając super.f() . Więc wyjście stałby się (chyba):

  • af()
  • B -> f()
  • A -> f()
  • A -> f()

Czy to możliwe? A jeśli tak, to w jaki sposób?

Uwaga: Nie jestem pewien, co praktyczne zastosowanie to będzie, ja po prostu staramy się nauczyć czegoś nowego: P

+0

Tak więc, w zasadzie, chcesz wywołać samą metodę?Nie sądzę, że możesz to zrobić. –

+0

Tak, dokładnie tego chcę. –

+0

@CharlesWhitfield Oczywiście metoda sama się nazywa. Nazywa się to metodą rekursywną. Pytanie OP brzmi: czy możliwe jest określenie macierzystej wersji metody z klasy nadrzędnej. – shmosel

Odpowiedz

5

Krótka odpowiedź brzmi „nie”, nie można tego zrobić.

Dłuższą odpowiedzią jest to, że pozwalając na złamanie wszelkiego rodzaju gwarancji dotyczących dziedziczenia. Twoja klasa B zasadniczo powiedziała: "Dostarczam teraz metodę kanoniczną dla public void f()". Ponieważ B zapewnia wspomnianą metodę, można ponownie zadzwonić do rodzica, aby go użyć (i coś, co jest bardzo przydatne).

Jeśli zezwolono na wykonanie tej samej czynności, to A zasadniczo pomija zachowanie, które chce zastąpić.

Dostępne są różne wzorce, które zapewniają zachowanie w postaci podobnej do, np. the Template Pattern

2

Ponieważ polimorfizm będą miały zastosowanie do wszystkich metod nadklasy obiektu, f że nazywa się będzie, że od typu wykonawczego obiektu zawsze - w tym przypadku, B, więc B „s f metoda będzie zawsze dzwonił. Tego nie można zmienić w Javie.

może być w stanie obejść ten problem, wykonując pracę f metody A „s w private metody, powiedzmy, foo, tak, że gdy f nazywa, foo wielokrotnie dzwonił. W A:

public void f() 
{ 
    foo(); 
} 

private void foo() { 
    System.out.println("A -> f()"); // Lie. 
    x = x + 4; 
    if (x < 15) this.foo(); //the "f"-call 
} 
Powiązane problemy