2010-06-25 49 views
24

我有一個類擴展了一個我需要覆蓋的類,但是我需要調用該類的父類。因爲我不能調用超級,因爲這將執行直接父母什麼是獲得我的父類的父母的最佳方式?Java:你如何訪問兩個級別的父類方法?

我確定這是一個基本問題,但是自從我一直在做任何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 */ } 
} 
+1

幾乎總是使用超級是不好的形式。唯一可能的例外就是過度方法稱之爲被忽略。在這種情況下,最好引入一個抽象或無所事事的方法,並用「原始」方法取代最終方法。但是這意味着你只能得到一杆。深厚的heirarchies是壞的反正... – 2010-06-25 13:07:08

+0

可能重複的[Java如何調用方法的祖父?](http://stackoverflow.com/questions/2584377/java-how-to-call-method-of-grand-父母)。也有關http://stackoverflow.com/questions/586363/why-is-super-super-method-not-allowed-in-java – finnw 2010-06-25 19:39:28

回答

27

你別:它違反了封裝。

可以說「不,我不想要我自己的行爲 - 我想要我父母的行爲」,因爲假設您只有在正確維護自己的狀態時纔會這樣做。

但是,您無法繞過父母的行爲 - 這將阻止其強制執行自己的一致性。如果父類想要允許您直接調用祖父方法,它可以通過單獨的方法公開該方法......但這取決於父類。

+0

謝謝,我明白了。我想我可能正在接近這個錯誤的方式。 – 2010-06-25 12:58:14

9

你不能因爲它已被覆蓋B.沒有A內的情況下

的事情是,你要調用的類A的方法,但是從實例?你已經實例化了C,它是一個擁有自己和從B繼承的方法的類。如果B重寫A的一個方法,則不能從C訪問它,因爲方法本身屬於C(不是方法B的,它一直延續下來,現在它在C)

可能的解決方法:

B不覆蓋myMethod()

C接收到A的實例,並將其保存爲一個類屬性。

myMethod()在一個是靜態的,你用A.myMethod()(我不推薦)

+0

謝謝,我看到我做錯了,但謝謝你的解釋。它幫助我理解。 – 2010-06-25 13:00:39

1

再說什麼pakore回答,你也可以連鎖super.myMethod()電話是否適合你。您將在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 
    .... 
    } 
} 

你最終會從呼叫myMethod的調用myMethod()從A從myMethod(),但間接地......如果你的作品。

+0

只有當您希望B.myMethod()與A.myMethod()完全相同時纔會起作用,這會導致以下問題:爲什麼地獄會在第一次覆蓋它? :) – pakore 2010-06-25 12:59:29

+0

@pakore:對不起...簡單的例子。當你需要的時候,根據一些條件,標誌等等,你可以調用super.myMethod。我將這個例子稍微改了一點,以使其更清晰 – 2010-06-25 13:03:02

+0

是的,我認爲你的意思是你現在已經更新了。請記住,您的解決方案與從C調用A.myMethod()不同,因爲B.myMethod()正在做其他事情,也許C不希望他們完成。 C只是想讓A.myMethod()完成,而不是一兩個。這就是爲什麼我說只有在A.myMethod()=== B.myMethod()時纔有效,而且它的覆蓋沒有意義:)。 – pakore 2010-06-25 13:07:49

0

您不能直接調用A的方法。在我遇到這種情況的少數案例中,解決方案是在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之間實現緊密耦合。

6

你在問什麼是壞的練習,你所說的是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

謝謝,我發現我這樣做是錯誤的,必須考慮更好的解決方案。我可能不必訪問那個盛大的父母方法去做我想做的事。 – 2010-06-25 12:58:59

0

我這種情況做的是:

使C類中的A類的對象,並訪問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 
相關問題