开发者

Java: Why could base class method call a non-exist method?

开发者 https://www.devze.com 2022-12-14 21:09 出处:网络
class BaseClass { private void f() { System.out.println(\"Baseclass f()\"); } public static void main(String[] args) {
class BaseClass {
    private void f() {
        System.out.println("Baseclass f()");
    }

    public static void main(String[] args) {
        BaseClass dc = new DerivedClass();
        dc.f();
    }
}

class DerivedClass extends BaseClas开发者_Python百科s {
    public void f() {
        System.out.println("DerivedClass f()");
    }
}

In my opinion, the object dc refers to should have only one non-override method - public void f() method,which make it(the public method) invisible when refered to with BaseClass reference.Since the object dc referes to does not have the private void f() method either because the DeriverClass could not inherit the private method,how could the object dc refers to call method f()?

thanks.


A common(ish) misconception is that private is per instance rather than per class.

For example:

class Foo
{
    private int a;

    public bar(final Foo other)
    {
        other.a = 5;
    }
}

Some people are under the impression that the code above should not work because "a" is "private". That is not the case, any Foo instance can access the private variables/methods of any other Foo instance. "private" just means that instances of other classes (other than Foo in this case) cannot access the private members.


Just to keep things straight, DerivedClass (DC) DOES inherit private void f() from BaseClass (BC). This inherited method is not accessible to DC but it is there because any method called in the BC part of DC has to have access to all of BC. So when you cast DC to a BC the inherited method becomes available. Now because you are running the code inside of the BC class it can access all of the private members of BC. If you moved the main to DC it shouldn't compile let alone run.


Four points:

(1) To elaborate on what vivyzer wrote, the code compiles because the main method in BaseClass has access to the class's own private methods. If you wrote the code as:

class BaseClass {
  private void f() { }
}

class DerivedClass {
  public void f() { }
}

class Bystander {
  public static void main() {
    BaseClass inst = new DerivedClass();
    inst.f();
  }
}

Then the code would not compile.

(2) This is allowed by the language to support the usecase where the author of a base class can add a new private method without worrying about other authors' derived types.

(3) You won't see this if the method was not private. If the base class's f() had package or protected visibility, then the method would be a virtual method.

(4) The reverse of point #2 is not supported by Java. Specifically, if a derived class has a private method, and a new version of the base type introduces a non-private method with the same signature, the derived class and new base class cannot be used together. There are other languages (for example C#) that addresses these sorts of modular, generational development questions more completely. If you are interested in this aspect, this is a good read on Artima: Versioning, Virtual, and Override


The main method is inside BaseClass and the private methods are visible to it. If main is in some other class, it will not compile.

0

精彩评论

暂无评论...
验证码 换一张
取 消