2011-04-25 97 views
1

我有一個擁有多個子級的抽象父類。我希望孩子能夠爲每個孩子都有一個相同的變量。我不希望傳遞一個構造函數給孩子來告訴它它的名字,因爲它可以被硬編碼時看起來很愚蠢。從我讀過的下面的內容中「隱藏」父變量實例變量並且不按照我的想法工作。Java繼承...困惑

public abstract class Parent { 
    public String name = "the parent"; 
    public getName(name); 
} 
public class Child1 extends Parent { 
    public String name = "Jon"; 
} 
public class Child2 extends Parent { 
    public String name = "Mary"; 
} 

Child1 c = new Child1(); 
c.getName(); // want this to return "Jon", but instead returns "the parent". 

需要明確的是,基本上是我想要的是像c.getClass()的getName(),但我不希望有這依賴於類的名字,而是一個硬編碼的結果值。

感謝

+1

究竟是什麼*被請求,我不是很清楚。你能澄清你想讓getName()返回你想要的原因嗎?你能寫出一系列應該(但可能不會)通過的斷言嗎? – 2011-04-25 18:55:20

+0

你想解決什麼問題?你能舉一個更好的例子說明爲什麼你需要一個類級別的標籤(每個實例都一樣)?也許我們可以提出一個更好的選擇。 – 2011-04-25 18:57:59

+0

我需要這個名字來支持遺留代碼,因爲我應該直接通過c.getClass()。getName()來使用類名,但是其餘的代碼沒有被寫入來支持這個。 – Tyler 2011-04-25 19:54:07

回答

3

取決於你實際上嘗試了,有一對夫婦的解決方案。一個是使子類父提供的名稱:

public abstract class Parent { 
    protected Parent(String name) { 
     this.name = name; 
    } 
    public getName() {return name;} 
} 
public class Child1 extends Parent { 
    public Child1() { 
     super("Jon"); 
    } 

} 
public class Child2 extends Parent { 
    public Child2() { 
     super("Mary"); 
    } 
} 

另一種是使用方法繼承like Isaac Truett suggests

+0

就是這樣!我最關心的是Parent的工作方式,那就是在調用沒有擴展Child的函數時,我必須更加小心,這意味着就我所知,我必須從類本身中使用Getters/Setters ,而不是直接訪問成員變量,因爲直接訪問可能導致獲取父變量,正如我們所見。 – Tyler 2011-04-25 19:50:06

3

創建有您的硬編碼名稱爲每個孩子static final String

public class Child1 extends Parent 
{ 
    public static final String NAME = "Jon"; 
} 
0

你需要覆蓋的getName功能,以得到你想要的結果。 因爲新的字符串名稱不替換母體的名稱,以便在的getName功能實際上是讀取父字符串

+0

我注意到了,我希望在Parent中保留儘可能多的代碼,所以我正在尋找避免這種情況的方法。如果這就是Java的工作方式,那就這樣做吧,但我只能先問你們。 – Tyler 2011-04-25 19:26:49

+0

@泰勒我相信StriplingWarrior的回答涉及在子類中編寫最少的代碼。 – 2011-04-25 19:43:18

3

使用,而不是一個場的方法(變量):

public abstract class Parent { 
    public String getName() { 
    return "the parent"; 
    } 
} 

public class Child1 extends Parent { 
    public String getName() { 
    return "Jon"; 
    } 
} 
public class Child2 extends Parent { 
    public String getName() { 
    return "Mary"; 
    } 
} 

在Java中,至少,你只能覆蓋方法,而不是變量。

另一種選擇是讓Parent的構造函數將名稱作爲參數。如果你這樣做,最好是Parent是抽象的,所有的構造函數都帶有name參數。然後,子類都需要在名稱,它通常會做這樣的事情經過:

public class Child1 extends Parent { 
    public Child1() { 
    this("Jon"); 
    // ... 
    } 
} 

其實,即使與方法重載的方法,它是很好,如果Parent是抽象的,所以你可以getName()抽象。

+0

這與所問的行爲相反嗎?不應該簡單的公共最終getName()解決問題? – bbaja42 2011-04-25 18:56:58

+0

@ bbaja42我對這個問題的解釋是,OP希望'getName()'根據所調用的實例的類別返回不同的名稱。我不確定那是什麼「相反」。在我不明白的問題中的一件事是最後一句中的「.getClass()」。這是要麼是錯字,要麼是Java中不可能的東西。 – 2011-04-25 19:03:15

+0

更仔細閱讀問題後;看起來你是對的。相反,我的意思是根據對象的類型返回不同的字符串。 – bbaja42 2011-04-25 19:06:12

6

你可以聲明父一個抽象方法,讓每個孩子實現該方法返回合適的名稱,比如:

public abstract class Parent { 
    public abstract String getName(); 
} 

public class Child1 extends Parent { 
    private static final String NAME = "Jon"; 
    public String getName() { return NAME; } 
} 

public class Child2 extends Parent { 
    private static final String NAME = "Mary"; 
    public String getName() { return NAME; } 
} 
0

爲什麼不使用構造函數?

public abstract class Parent { 
    public String name = "the parent"; 
    public String getName() { 
     return name; 
    } 
    public void setName(String s){ 
     name = s; 
    } 
} 
public class Child1 extends Parent { 
    public Child1() { 
     setName("Jon"); 
    } 
} 
public class Child2 extends Parent { 
    public Child2() { 
     setName("Mary"); 
    } 
} 

Child1 c = new Child1(); 
c.getName(); 

//打印「喬恩

+0

我的例子是抽象的,但實際上你建議的實現看起來像:PhotoClass pc = new PhotoClass(「photo」),它看起來很愚蠢,開發人員必須知道總是用「photo」這個詞來實例化它,否則它不會工作。 – Tyler 2011-04-25 19:25:23

+0

如果你說你的問題中'PhotoClass'類似於'Parent',那麼不行,因爲你在你的問題中宣稱它是抽象的,所以你不能寫'新的PhotoClass(「Photo」)。如果「家長」不是抽象的,那麼顯着改變問題。 – 2011-04-25 19:31:03

+0

PhotoClass是孩子。 – Tyler 2011-04-25 19:45:52

1

之所以你到getName()調用不返回孩子的名字是因爲你的孩子中創建一個新變量調用名稱。試試這個:

​​

您將看到:

the parent : Jon 

正確的方法來設置子成父name變量的名稱是說:

super.name = "Jon"; 
0

你可以這樣做這使用Java反射...但它不是一個很乾淨的做事方式:

public abstract class Parent { 
    public String name = "the parent"; 
    public String getName() throws Exception { return getClass().getField("name").get(this).toString(); } 
} 

雖然我認爲艾薩克的方法是解決問題的最好方法。

+0

不,請。就是不行。 – 2011-04-25 19:41:40

+0

@Isaac容易有殺手,這不是他建議我們都從現在開始只吃菠菜...雖然它是接近:) – 2011-04-25 19:59:24

+0

@ josh.trow我寧願吃菠菜(嬰兒,香醋香醋,請)比調試濫用反射的代碼。可悲的是,後者的職業付出了更多。 :) – 2011-04-25 21:58:26