Это - вопрос, меня спросили в интервью: у Меня есть класс A с членами парламента, не занимающими официального поста, и Класс B расширяет A. Я знаю, что к членам парламента, не занимающим официального поста класса нельзя получить доступ, но вопрос: Я должен получить доступ к членам парламента, не занимающим официального поста класса A от класса B, а не создать переменные с тем же значением в классе B.
Можно использовать установщики и приемники класса A. Это дает такое же ощущение, как если бы вы использовали объект класса A.
-121--2172897-Архитектура нарушена. Частные участники являются частными, так как не требуется доступ к ним вне класса и к друзьям.
Вы можете использовать взломы друзей, средства доступа, продвигать участника или # определять частные общедоступные
(heh). Но это все краткосрочные решения - вероятно, придется на каком-то этапе вернуться к нарушенной архитектуре.
Вы думали о том, чтобы сделать их защищенными ? Просто чтобы быть уверенным, что вы знаете об этом варианте, если вы затем простите меня за поднятие этой пустяки;)
Личное будет скрыто до тех пор, пока вы не получите к нему правильный доступ. Например, геттеры или сеттеры программиста, написавшего Parent. Если они тоже не видны, примите тот факт, что они только частные и недоступны для вас. Почему именно вы хотите это сделать ??
Если я правильно понимаю вопрос, вы можете изменить частный
на защищенный
. Защищенные переменные доступны для подклассов, но в остальном ведут себя как частные переменные.
Вы не можете получить доступ к закрытым членам из родительского класса. Вы сделали его защищенным или имеете защищенный / общедоступный метод, который имеет к ним доступ.
РЕДАКТИРОВАТЬ : Это правда, что вы можете использовать отражение. Но нарушать инкапсуляцию - это необычно и не очень хорошая идея.
Отражение? Опуская импорт, это должно сработать:
public class A {
private int ii = 23;
}
public class B extends A {
private void readPrivateSuperClassField() throws Exception {
Class<?> clazz = getClass().getSuperclass();
Field field = clazz.getDeclaredField("ii");
field.setAccessible(true);
System.out.println(field.getInt(this));
}
public static void main(String[] args) throws Exception {
new B().readPrivateSuperClassField();
}
}
Это не сработает, если вы сделаете что-то подобное перед вызовом readPrivateSuperClassField ();
:
System.setSecurityManager(new SecurityManager() {
@Override
public void checkMemberAccess(Class<?> clazz, int which) {
if (clazz.equals(A.class)) {
throw new SecurityException();
} else {
super.checkMemberAccess(clazz, which);
}
}
});
И есть другие условия, при которых подход Reflection победил не работает. См. документацию API для SecurityManager и AccessibleObject для получения дополнительной информации. Спасибо CPerkins за указание на это.
Я надеюсь, что они просто проверяли ваши знания, а не искали реального применения этого материала ;-) Хотя я думаю, что такой уродливый хак, как этот выше, может быть законным в некоторых крайних случаях.
Интервьюер либо проверял ваши знания модификаторов доступа, либо ваш подход к изменению существующих классов, либо и то, и другое.
Я бы перечислил их (public, private, protected, package private) с объяснением каждого. Затем сказал бы, что класс A нужно изменить, чтобы разрешить доступ к этим членам из класса B, либо добавив сеттеры и геттеры, либо изменив модификаторы доступа членов. Или класс B может использовать отражение. Наконец, обсудите плюсы и минусы каждого подхода.
Используя публичные аксессоры (геттеры и сеттеры) приватных членов A ...
Архитектура нарушена. Частные члены являются частными, потому что вы не хотите, чтобы к ним обращались за пределами класса и друзей.
Вы можете использовать хаки друзей, аксессоры, продвигать член или #define private public
(хех). Но это все краткосрочные решения - вероятно, на каком-то этапе вам придется пересмотреть сломанную архитектуру.
Вы можете использовать сеттеры и геттеры класса A. Это дает такое же ощущение, как если бы вы использовали объект класса A.
Не знаю как в Java, но в некоторых языках вложенные типы могут делать это:
class A {
private string someField;
class B : A {
void Foo() {
someField = "abc";
}
}
}
В противном случае используйте метод-доступ или защищенное
поле (хотя ими часто злоупотребляют).