简体   繁体   中英

Are private fields inherited by the subclass?

I have read that a subclass cannot inherit private fields or methods. However, in this example

class SuperClass {
    private int n=3;
    int getN() {
        return n;
    }
}

class SubClass extends SuperClass {
    public static void main(String[] args) {
        SubClass e = new SubClass();
        System.out.println("n= " + e.getN());
    }
}

When I run main I get the output as n=3 . Which seems that SubClass is inheriting the private attribute n from SuperClass .

So, please explain what's going on here. Thank you.

The subclass 'has' the fields of its superclass, but does not have access to them directly. Similarly, the subclass 'has' the private methods, but you cannot call or override them from the subclass directly.

In the Java documentation on inheritance , it says that

A subclass does not inherit the private members of its parent class.

However, I find it more useful to think of it as

A subclass inherits the private members of its parent class but does not have access to them

but this boils down to sematics.

You're inheriting and using the getn() method, which is package-private and available from the subclass (since both are inherently in the same package in this case.) You can't access n directly because it's private. It's the getn() method that has access to n because it's in the same class as n , and you have access to the getn() method because it's not private.

If you did:

System.out.println("n= "+e.n+"");

...in place of your current line, then it wouldn't compile for the above reason.

It's perfectly normal behaviour to expose private variables through setter / getter methods, which is essentially what you're doing here. The difference is with this approach you have the potential to check / restrict / alter / log / anything the value of the variable when you get it or set it, and you can do so without making breaking changes when your code compiles. You can't do the same if you just make a field public and let people access it directly.

This is a topic worth of discussion. The confusion arises because, technically, the subclass inherits the private fields, because the private fields exist in the subclass, so that when you call getN(), it returns the value of n. So the field n exists in the subclass. If it didn't exist, then when you called getN(), it would issue an error, since the field n doesn't exist. The thing is, it does exist, and since it were declared in the superclass, it technically was inherited by the subclass.

However, we (Java programmers and the java official documentation about inheritance ) don't consider this inheritance. By our convention, this is not considered inheritance, because you cannot access the value of those fields directly. It's almost as if they weren't yours, since the only way to access them is using what everybody else(classes that are not subclasses of that superclass) use (getters/setters).

So, conceptually speaking, private fields are not inherited (although they exist in the subclass).

I think teachers should make this point a lot more clear than they do. After deeply looking at it, it really is confusing.

Its because object of child class is accessing method in the parent class which is not private. And that method getN() is returning the private attribute of the parent class. This is why value of private attribute of the parent class is being inherited. I hope this helps!

This is a great topic which dragged me and my professor into a quarrel. But he proved his mettle by explaining me with patience.

Accessibility has nothing to do with Inheritance. All the attributes and methods are inherited by the child classes irrespective of the access modifiers.

Though the child class can't access the attributes or methods, it still inherits them!

Every programming language has its own interpretation of the above concept of inheritance and accessibility.

The subclass can access the private fields of the super class only via the public or protected access methods (getters, setters).

Try to access the private variable directly and see that it won't work: eg

// won't work
System.out.println("n= "+e.n+"");

This will fail to compile:

class NewExample extends Example {
    public static void main (String[] args) {
        NewExample e = new NewExample();
        System.out.println("n=" + e.n);
    }
}

Because the variable is declared private , subclasses do not have direct access to it. Same as with methods. If you declared getn() as private , you wouldn't be able to access that either. If you want a subclass to have direct access to n , you can declare it as protected int n and that will allow subclasses to modify it directly. This may or may not be desirable in a lot of circumstances.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM