In Java, why can't a super-class method access protected or private methods/variables from a sub-class instance?

删除回忆录丶 提交于 2019-11-30 20:04:56

It's as simple as it's a violation of encapsulation. Another class should not be able to reach into your class and be messing around with things, even if you generalize that class. How does a Vehicle know anything about a Car for example? The whole point of a base class is to provide for the sub-classes, but like an over-protective parent, what you're suggesting would be too much.

To answer your update question (as the original question is well answered already) the purpose of private is to hide implementation details so that those implementation details don't become dependencies. This is the essence of object oriented programing - encapsulation ensuring that complexity is kept manageable by keeping different parts isolated to their own area.

Since the class knows about its own implementation - it defines it, there is nothing gained in limiting access to other instances, since the class implementation declares all the private instances it is already exposed to all of these details.

Hiding it in this case would in fact increase complexity as you would have to add an additional access level to allow class-level visibility instead of instance level visibility without actually really encapsulating any further complexity.

It's all about inheritance and encapsulation.

Java's visibility rules state that

  1. private members can only be accessed in the class that defines them
  2. protected members can only be access in
    • the class that defines them
    • subclasses of the class that defines them
    • other classes in the same package as the class that defines them

Of course, as you mention, in reflection you can change the rules (unless a SecurityManager forbids it)

I tend to look it more from a pragmatic and realistic standpoint:

public class Test1 {
    private int a = 1;

    public static void main(String s[]) {
        System.out.println((new Test1()).a);
        System.out.println((new Test1()).getA());
        System.out.println((new Test2()).getA());
    }

    public int getA() { return a; }
}

class Test2 extends Test {
    private int a = 2;

    public int getA() { return a; }
}

What syntax would you propose Test1 use to access private member a in Test2. When Test1 is written, Test2 may not even exist.

As well, a base-class (super-class) doesn't know when it has been inherited from. To allow a base-class to know when it has been inherited, you would have to be able to modify the base-class when inheriting from it. Are you suggesting that I should somehow modify my local copy of ArrayList when I write:

class MyArrayList extends ArrayList

And what happens the day I decide to run my code on your computer, do you get my modified copy of ArrayList that knows about MyArrayList, or do I modify the copy on your computer somehow?

Could these issues be overcome somehow? Certainly. Is there any value in allowing it? None that I can see.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!