How to access the private variables of a class in its subclass?

Viewed 53262

This is a question I was asked in an interview: I have class A with private members and Class B extends A. I know private members of a class cannot be accessed, but the question is: I need to access private members of class A from class B, rather than create variables with the same value in class B.

28 Answers

The interviewer was either testing your knowledge of access modifiers, or your approach to changing existing classes, or both.

I would have listed them (public, private, protected, package private) with an explanation of each. Then gone on to say that class A would need to be modified to allow access to those members from class B, either by adding setters and getters, or by changing the access modifiers of the members. Or class B could use reflection. Finally, talk about the pros and cons of each approach.

Reflection? Omitting imports, this should work:

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();
    }

}

It'll not work if you do something like that before the of invocation 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);    
            }
        }
    });

And there are other conditions under which the Reflection approach won't work. See the API docs for SecurityManager and AccessibleObject for more info. Thanks to CPerkins for pointing that out.

I hope they were just testing your knowledge, not looking for a real application of this stuff ;-) Although I think an ugly hack like this above can be legit in certain edge cases.

The architecture is broken. Private members are private because you do not want them accessed outside the class and friends.

You can use friend hacks, accessors, promote the member, or #define private public (heh). But these are all short term solutions - you will probably have to revisit the broken architecture at some stage.

By using public accessors (getters & setters) of A's privates members ...

You cannot access private members from the parent class. You have make it protected or have protected/public method that has access to them.

EDIT : It is true you can use reflection. But that is not usual and not good idea to break encapsulation.

If I'm understanding the question correctly, you could change private to protected. Protected variables are accessible to subclasses but behave like private variables otherwise.

You can use the setters and getters of class A. Which gives same feeling as if You are using a class A's object.

Have you thought about making them protected ? Just to be sure you are aware of this option, if you are then pardon me for bringing up this trivia ;)

Private will be hidden until you have been given the right access to it. For instance Getters or setters by the programmer who wrote the Parent. If they are not visible by that either then accept the fact that they are just private and not accessible to you. Why exactly you want to do that??

Related