2011-02-04 56 views
40

靜態字段我剛開始就用一個例子,最能解釋它:的Java:在抽象類

public abstract class A{ 
    static String str; 
} 

public class B extends A{ 
    public B(){ 
     str = "123"; 
    } 
} 

public class C extends A{ 
    public C(){ 
     str = "abc"; 
    } 
} 

public class Main{ 

    public static void main(String[] args){ 
     A b = new B(); 
     A c = new C(); 
     System.out.println("b.str = " + b.str); 
     System.out.println("c.str = " + c.str); 
    } 
} 

這將打印出:

b.str = ABC

℃。 str = abc

但我想要一個解決方案,其中每個實例化超類的子類都有自己的自己的類變量,同時我想以便能夠通過抽象超類中定義的標識符或方法調用來引用該類變量。

所以我想輸出是:

b.str = 123

c.str = ABC

是不是可行?

回答

3

把靜態varibale在每個子類,並添加一個(而不是靜態)抽象方法的抽象超:

abstract String getStr(); 

然後通過返回這個特殊的靜態字段實現每個子類中getStr()方法子類。

public class B extends A { 
private static String str; 

    @Override 
    public String getStr() { 
    return B.str; 
    } 
} 
+0

我編輯了我的帖子,是一個錯誤..接受。事情是,我需要每個對象都有一個對同一子類的所有對象共享的值的引用,但不一定在不同子類的對象之間共享。 – Tommy 2011-02-04 14:00:22

+0

我也更新了我的答案 – Ralph 2011-02-04 14:03:41

+0

當然。謝謝。 – Tommy 2011-02-04 14:11:00

6
public abstract class A { 
    private String str; 
    public String getStr() { return str;} 
    protected void setStr(String str) { this.str = str; } 
} 

然後,你就可以有

B b = new B(); 
b.getStr(); 

setter和getter是我另外,你可以通過簡單地使變量非靜態去。

更新如果你想擁有靜態每子類,那麼你可以有:

protected static Map<Class, String> values; 
public abstract String getValue(); 

然後:

public String getValue() { 
    values.get(getClass()); 
} 
public void setValue(String value) { 
    values.set(getClass(), value); 
} 

但是這通常是一個壞主意。

+0

即使沒有getter和setter,這也可以工作。然後確保str變量是公開的,這是不推薦的。 – 2011-02-04 14:04:37

2

只有靜態變量的一個實例是存在於系統中。被加載的類前

靜態變量將加載到系統中的開始。

因爲這兩個時間abc打印是因爲你在最後設置str的值爲abc。

2

這將打印您需要的輸出:

public abstract class A{ 
} 

public class B extends A{ 
    static String str; 

    public B(){ 
     str = "123"; 
    } 
} 

public class C extends A{ 
    static String str; 

    public C(){ 
     str = "abc"; 
    } 
} 

public class Main{ 

    public static void main(String[] args){ 
     A a = new B(); 
     A c = new C(); 
     System.out.println("B.str = " + B.str); 
     System.out.println("C.str = " + C.str); 
    } 
} 
45

如果你想要類B和C有不同的靜態變量,你需要在這些類中聲明的變量。基本上,靜態成員和多態不會在一起。

注意,通過引用訪問靜態成員是在可讀性方面有真的糟糕的主意 - 這使得它看起來這取決於參考的價值,當它不是真的。所以,當前的代碼將無法編譯,甚至當你移動str到B和C.相反,你需要

System.out.println("b.str = " + B.str); 
System.out.println("c.str = " + C.str); 

如果你真的需要多態訪問值(即通過一個實例)然後一個選項是製作一個多態吸氣劑:

public class A { 
    public abstract String getStr(); 
} 

public class B extends A { 
    private static String str = "b"; 

    @Override public String getStr() { 
     return str; 
    } 
} 

(和C相同)。

這樣你就可以得到你想要的行爲,而不是每個實例都有一個單獨的變量,但是你仍然可以多形地使用它。它是一個實例成員返回這樣一個靜態值有點奇怪,但你使用值類型的多態性,基本上...

2

既然你硬編碼在子類中的價值或str反正,你可以做這樣的事情:

public abstract class A{ 
    public abstract String getStr(); 
} 

public class B extends A{ 
    public String getStr(){ 
     return "123"; 
    } 
} 

public class C extends A{ 
    public String getStr(){ 
     return "abc"; 
    } 
} 

這將做你的情況的伎倆。

當然,那麼你應該通過方法調用它,就像這樣:

public class Main{ 

    public static void main(String[] args){ 
     A b = new B(); 
     A c = new C(); 
     System.out.println("b.str = " + b.getStr()); 
     System.out.println("c.str = " + c.getStr()); 
    } 
} 
0

我想接近這個是使用一個單獨的B類和C模仿靜態方法和字段的一種方式。該既可擴展抽象類A,但將有str自己的價值觀..

1

這是我做的,以避免必須實現在每個子類中的方法相同。它基於Bozho的答案。也許它可以幫助某人。

import java.util.HashMap; 
import java.util.Map; 

/** 
* 
* @author Uglylab 
*/ 
public class SandBox { 

    public static void main(String[] args) { 
     A b = new B(); 
     A c = new C(); 
     System.out.println("b.str = " + B.getStr(b.getClass())); 
     System.out.println("c.str = " + C.getStr(c.getClass())); 
    } 

} 
abstract class A{ 
    protected static Map<Class, String> values = new HashMap<>(); 


    public static String getStr(Class<? extends A> aClass) { 
     return values.get(aClass); 
    } 

    public static void setStr(Class<? extends A> aClass, String s) { 
     values.put(aClass, s); 
    } 

} 

class B extends A{ 
    public B(){ 
     setStr(this.getClass(),"123"); 
    } 
} 

class C extends A{ 
    public C(){ 
     setStr(this.getClass(),"abc"); 
    } 
}