2013-01-14 22 views
1

可能是一個非常基本的Java問題。從抽象類調用未聲明的超級方法時獲取當前對象屬性

我有一個抽象類,簡化IT:

public abstract class A{ 
    private String value = "A" ; // I want it undeclared, but set it for testing purpouse 

    public String getValue(){ 
    return value ; 
    } 
} 

然後,我有一個類擴展它:

public abstract class B{ 
    private String value = "B" ; 
} 

所以這個問題我已經是,創建通過類的B的實例時A,並調用getValue(),它總是返回「A」:

A b = new B(); 
b.getValue(); // returns "A" 

如何獲得B調用超級會面使用他自己的屬性而不必重複代碼?它現在太長了,它被擴展到許多不同的類,只有它的屬性值不同,它們都使用與超類相同的方法。

謝謝!

編輯:

對不起,我不是那麼具體。我有很多屬性,以及一些處理這些屬性的方法。擴展類更改這些屬性,但我想使用擴展類實例化對象的超級方法,而不必聲明它們兩次。如果有幫助,我正在處理servlets上下文。

Config.java

public abstract class Config { 
    private String someValue1 ; 
    ... 
    private String someValuen ; 

    public void export(ServletContext cxt){ 
     cxt.setAttribute("someValue1", someValue1); 
     ... 
     cxt.setAttribute("someValuen", someValuen); 
    } 
} 

SomeConfig.java

public class SomeConfig { 
    private String someValue1 = "something" ; 
    ... 
    private String someValuen = "something else" ; 
} 

SomeServlet.java

ServletContext cxt = getServletContext() ; 
Config config = new SomeConfig(); 
config.export(cxt); 

要清楚,性能都有着不同的名字。我使用他們的jsp爲:$ {} someValuen

回答

5

爲什麼它不工作的原因是,只有方法可以被覆蓋 - 可變成員,而不是隱藏(如果你從你的B級打印value,這將是"B" )。

對於具體的例子,我會用一個專門的構造函數(這我已經做保護,以防止客戶端類訪問它):

public abstract class A { 
    private final String value; 

    public A() { //for internal/testing use only 
     value = "A"; 
    } 

    protected A(String value) { 
     this.value = value; 
    } 

    public String getValue(){ 
     return value ; 
    } 
} 

則B可以簡單地調用相關的構造:

public class B extends A { 
    public B() { 
     super("B"); 
    } 
} 

EDIT

實施例與ConfigHolder

public class ConfigHolder { 

    String value1; 
    String value2; 
    String value3; 

    public ConfigHolder value1(String value1) { 
     this.value1 = value1; 
     return this; 
    } 
    //same for other variables 
} 

然後在A類:

public abstract class A { 
    private final ConfigHolder config; 

    public A() { 
     this.config = new ConfigHolder() 
       .value1("value1") 
       .value2("value2"); 
    } 

    protected A(ConfigHolder config) { 
     this.config = config; 
    } 

    public void export(ServletContext cxt){ 
     cxt.setAttribute("someValue1", builder.value1); 
     ... 
     cxt.setAttribute("someValuen", builder.valuen); 
    } 
} 

而在B:

public class B extends A { 
    public B() { 
     super(new ConfigBuilder() 
        .value1("value1InB") 
        .value2("value2InB")); 
    } 
} 
+0

感謝您的回答!實際上它比較複雜,A有很多標準屬性,那些沒有得到特定的方式,外部對象被傳遞給這些方法,並且這些屬性與這個外部對象一起使用,所以它有很多屬性可以做到這一點那樣。更具體地說,我傳遞了一個servlet上下文,並且爲每個超類設置了一個分支,所以我想在那裏聲明方法,並且在擴展類中有不同的配置。 –

+0

也許向我們展示如何設置和檢索其中一個屬性,以便它更清晰? –

+0

我編輯了這個問題。 –

0

要做到這一點:A b = new B(); B必須的

另外一個子類,抽象類不能被實例化,即不能創建抽象類對象。如果你試圖編譯器會產生一個錯誤。

public abstract class A{ 
    private String value = "A" ; 

    public String getValue(){ 
    return value ; 
    } 
} 


public class B extends A{ 
    private String value ; 
    public B(){ 
     value = "B"; 
    } 
} 

現在你可以做B notAbstractClass = new B();

而且做notAbstractClass.getValue();它必須返回「B」時

0

我只是想出了一個簡單的方式與構造函數來做到這一點,改變了超類屬性保護(感謝@assylias回答): Config.java

public abstract class Config { 
    protected String someValue1 ; 
    ... 
    protected String someValuen ; 

    public void export(ServletContext cxt){ 
     cxt.setAttribute("someValue1", someValue1); 
     ... 
     cxt.setAttribute("someValuen", someValuen); 
    } 
} 

SomeConfig.java

public class SomeConfig { 
    public SomeConfig(){ 
    someValue1 = "something"; 
    ... 
    someValuen = "something else"; 
    } 
}