2011-03-31 136 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(); 
    } 
}