Reputation: 10662
I would like to declare a data member of a superclass, private:
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;
}
}
As you can see, I have a problem here: superclass can't access verySensitive because it's private, but I don't want to make verySensitive protected because it's... sensitive.
Also note that setVerySensitive was made abstract because checking against valid values can only be done after superclass has been constructed.
Can you recommend an elegant way of getting out of this "catch 22" situation?
Upvotes: 1
Views: 5009
Reputation: 4289
Use reflect:
// 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();
}
}
Upvotes: 3
Reputation: 8899
Just how "sensitive" is this value? You may want to look into configuring a SecurityManager to prevent accessing the private field via reflection.
Upvotes: 1
Reputation: 234795
I suggest something like this:
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
}
}
This is similar to EboMike's suggestion, but it leaves setVerySensitive(int)
with package access instead of making it private.
Upvotes: 5
Reputation: 86774
Add
protected void setVerySensitive(int val) { verySensitive = val; }
in the superclass, then use that in the subclass to set the value.
Upvotes: 0
Reputation: 31
sorry, no way out.
Either it is private and only you can access it, or it is protected and it is part of your subclass signature.
Upvotes: 1
Reputation: 43023
Provide a protected method the child class can access for actually change verySensitive value.
Upvotes: 0
Reputation: 3523
I think the only answer that fits your criteria would be this:
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);
}
}
It's not much different than simply making verySensitive
protected but you have to be able to access it somewhere.
Upvotes: 1
Reputation: 77752
How about making the checking abstract, but the setting itself private?
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
}
}
Upvotes: 6