2011-03-31 166 views
1

我想聲明一個超類的數據成員,私營:訪問私有數據成員

public abstract class superclass { 
    private int verySensitive; 

    abstract int setVerySensitive(int val); // must be overriden by subclass to work properly 
} 


public class subclass extends superclass { 

    @Override 
    protected int setVerySensitive(int val) { 
    if (val > threshLow && val < threshHigh) // threshHigh is calculated in superclass constructor 
     verySensitive = val; 
    } 
} 

正如你所看到的,我這裏有一個問題:超不能訪問verySensitive,因爲它是私人的,但我不想做出非常敏感的保護,因爲它非常敏感。

另請注意,setVerySensitive是抽象的,因爲檢查有效值只能在超類構造完成後才能完成。

你能推薦一種擺脫這種「捕捉22」情況的優雅方式嗎?

+0

這不就是語言的_feature_?你只是選擇設置爲受保護的,如果它需要繼承 – 2011-03-31 19:42:48

+0

@Greg Flynn你是對的,在C++中這不是問題,因爲受保護的數據成員可以被子類訪問,但仍然對類的用戶隱藏。在Java中,protected使它可用於整個包,而不僅僅是超類。 – 2011-03-31 20:00:40

回答

5

我建議是這樣的:

public abstract class superclass { 
    private int verySensitive; 

    final int setVerySensitive(int val) { 
    if (checkVerySensitive(val)) { 
     verySensitive = val; 
    } 
    } 
    protected abstract boolean checkVerySensitive(int val); 
} 


public class subclass extends superclass { 

    @Override 
    protected boolean checkVerySensitive(int val) { 
    return val > threshLow && val < threshHigh; // threshHigh is calculated in superclass constructor 
    } 
} 

這類似於EboMike的建議,但它留下setVerySensitive(int)與包訪問,而不是使其成爲私人的。

+0

這是迄今爲止最實用的解決方案。 +1 – 2011-03-31 19:55:45

6

如何使檢查抽象,但設置自己私人?

public abstract class superclass { 
    private int verySensitive; 

    abstract boolean verifySensitiveValue(int val); // must be overriden by subclass to work properly 

    private void setVerySensitiveValue(int val) { 
    if (verifySensitiveValue(val)) { 
     verySensitive = val; 
    } 
    } 
} 


public class subclass extends superclass { 

    @Override 
    protected boolean verifySensitiveValue(int val) { 
    return (val > threshLow && val < threshHigh); // threshHigh is calculated in superclass constructor 
    } 
} 
+0

如果超類的用戶實際上可以調用setVerySensitiveValue(),這是一個很好的解決方案。謝謝! – 2011-03-31 19:52:17

1

我覺得適合你的標準是唯一的答案是:

public abstract class superclass { 
    private int verySensitive; 

    abstract int setVerySensitive(int val); // must be overriden by subclass to work properly 

    protected void setVerySensitiveForReal(int val) { 
    verySensitive = val; 
    } 
} 


public class subclass extends superclass { 

    @Override 
    protected int setVerySensitive(int val) { 
    if (val > threshLow && val < threshHigh) // threshHigh is calculated in superclass constructor 
     setVerySensitiveForReal(val); 
    } 
} 

這不是比簡單地使verySensitive保護太大的不同,但你必須要能夠訪問它地方

+0

如果團隊中的另一位程序員錯誤地調用了setVerySensitiveForReal()方法會帶來危險的值會怎麼樣? – 2011-03-31 19:50:50

0

提供受保護的方法,子類可以訪問實際上改變非常敏感的值。

1

對不起,沒有出路。

要麼它是私人的,只有你可以訪問它,或者它是受保護的,它是你的子類簽名的一部分。

0

添加

protected void setVerySensitive(int val) { verySensitive = val; } 

超類,然後使用在子類設置數值。

+0

setVerySensitive必須是抽象的,因爲檢查有效值只能在超類構造完成後才能完成。 – 2011-03-31 19:47:33

+0

不,超類方法是受保護的,只有子類纔會使用它來實際更改值,假設驗證是在子類方法中完成的。 – 2011-03-31 19:49:05

3

使用反映:

// SubClass.java 
import java.lang.reflect.*; 

class SuperClass { 
    private String privateField = "This is Private"; 
    public SuperClass(){ 
    } 
} 
class SubClass extends SuperClass { 
    void getPrivateField(){ 
     Field f = null; 
     try { 
      f = SuperClass.class.getDeclaredField("privateField"); 
     } catch (NoSuchFieldException nsfe){ 
      throw new Error(); 
     } 
     f.setAccessible(true); 
     try { 
      System.out.println(f.get(this)); 
     } catch (IllegalAccessException iae){ 
      throw new Error(); 
     } 
    } 
    public static void main(String[] args){ 
     new SubClass().getPrivateField(); 
    } 
}