Доступ к личному члену данных из подкласса - PullRequest
1 голос
/ 31 марта 2011

Я хотел бы объявить члена данных суперкласса закрытым:

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"?

Ответы [ 8 ]

6 голосов
/ 31 марта 2011

Как насчет сделать проверку абстрактной, но саму настройку приватной?

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
  }
}
5 голосов
/ 31 марта 2011

Я предлагаю что-то вроде этого:

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) с доступом к пакету, а не делает его закрытым.

3 голосов
/ 31 марта 2011

Использование отражения:

// 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();
    }
}
1 голос
/ 31 марта 2011

Насколько «чувствительна» эта величина?Возможно, вы захотите взглянуть на настройку SecurityManager для предотвращения доступа к приватному полю через отражение.

http://aminurrashid.com/english/java/core-java/prevent-reflection-to-access-private-methods-and-members-in-java-classes.html

1 голос
/ 31 марта 2011

извините, нет выхода.

Либо это личное сообщение, и только вы можете получить к нему доступ, либо оно защищено и является частью вашей подписи подкласса.

1 голос
/ 31 марта 2011

Я думаю, что единственный ответ, который соответствует вашим критериям, будет следующим:

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 голосов
/ 31 марта 2011

Добавьте

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

в суперкласс, затем используйте его в подклассе для установки значения.

0 голосов
/ 31 марта 2011

Предоставляет защищенный метод, к которому дочерний класс может получить доступ для фактического изменения значения VerySensitive.

...