Как получить доступ к частным переменным класса в его подклассе?

Это - вопрос, меня спросили в интервью: у Меня есть класс A с членами парламента, не занимающими официального поста, и Класс B расширяет A. Я знаю, что к членам парламента, не занимающим официального поста класса нельзя получить доступ, но вопрос: Я должен получить доступ к членам парламента, не занимающим официального поста класса A от класса B, а не создать переменные с тем же значением в классе B.

19
задан Nathaniel Ford 19 August 2014 в 18:30
поделиться

10 ответов

Можно использовать установщики и приемники класса A. Это дает такое же ощущение, как если бы вы использовали объект класса A.

-121--2172897-

Архитектура нарушена. Частные участники являются частными, так как не требуется доступ к ним вне класса и к друзьям.

Вы можете использовать взломы друзей, средства доступа, продвигать участника или # определять частные общедоступные (heh). Но это все краткосрочные решения - вероятно, придется на каком-то этапе вернуться к нарушенной архитектуре.

-121--2172904-

Вы думали о том, чтобы сделать их защищенными ? Просто чтобы быть уверенным, что вы знаете об этом варианте, если вы затем простите меня за поднятие этой пустяки;)

1
ответ дан 30 November 2019 в 02:01
поделиться

Личное будет скрыто до тех пор, пока вы не получите к нему правильный доступ. Например, геттеры или сеттеры программиста, написавшего Parent. Если они тоже не видны, примите тот факт, что они только частные и недоступны для вас. Почему именно вы хотите это сделать ??

0
ответ дан 30 November 2019 в 02:01
поделиться

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

2
ответ дан 30 November 2019 в 02:01
поделиться

Вы не можете получить доступ к закрытым членам из родительского класса. Вы сделали его защищенным или имеете защищенный / общедоступный метод, который имеет к ним доступ.

РЕДАКТИРОВАТЬ : Это правда, что вы можете использовать отражение. Но нарушать инкапсуляцию - это необычно и не очень хорошая идея.

5
ответ дан 30 November 2019 в 02:01
поделиться

Отражение? Опуская импорт, это должно сработать:

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 за указание на это.

Я надеюсь, что они просто проверяли ваши знания, а не искали реального применения этого материала ;-) Хотя я думаю, что такой уродливый хак, как этот выше, может быть законным в некоторых крайних случаях.

11
ответ дан 30 November 2019 в 02:01
поделиться

Интервьюер либо проверял ваши знания модификаторов доступа, либо ваш подход к изменению существующих классов, либо и то, и другое.

Я бы перечислил их (public, private, protected, package private) с объяснением каждого. Затем сказал бы, что класс A нужно изменить, чтобы разрешить доступ к этим членам из класса B, либо добавив сеттеры и геттеры, либо изменив модификаторы доступа членов. Или класс B может использовать отражение. Наконец, обсудите плюсы и минусы каждого подхода.

34
ответ дан 30 November 2019 в 02:01
поделиться

Используя публичные аксессоры (геттеры и сеттеры) приватных членов A ...

6
ответ дан 30 November 2019 в 02:01
поделиться

Архитектура нарушена. Частные члены являются частными, потому что вы не хотите, чтобы к ним обращались за пределами класса и друзей.

Вы можете использовать хаки друзей, аксессоры, продвигать член или #define private public (хех). Но это все краткосрочные решения - вероятно, на каком-то этапе вам придется пересмотреть сломанную архитектуру.

6
ответ дан 30 November 2019 в 02:01
поделиться

Вы можете использовать сеттеры и геттеры класса A. Это дает такое же ощущение, как если бы вы использовали объект класса A.

1
ответ дан 30 November 2019 в 02:01
поделиться

Не знаю как в Java, но в некоторых языках вложенные типы могут делать это:

    class A {
        private string someField;
        class B : A {
            void Foo() {
                someField = "abc";
            }
        }
    }

В противном случае используйте метод-доступ или защищенное поле (хотя ими часто злоупотребляют).

0
ответ дан 30 November 2019 в 02:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: