31

There something ambiguous about this idea and I need some clarifications.

My problem is when using this code:

public class B {

    private void don() {
        System.out.println("hoho private");
    }
    public static void main(String[] args) {
        B t = new A();
        t.don();
    }
}

class A extends B {
    public void don() {
        System.out.println("hoho public");
    }
}

The output is hoho private.

Is this because the main function is in the same class as the method don, or because of overriding?

I have read this idea in a book, and when I put the main function in another class I get a compiler error.

Chris Martin
  • 30,334
  • 10
  • 78
  • 137
basel man
  • 471
  • 1
  • 5
  • 10
  • 1
    Some good reading: http://stackoverflow.com/questions/2000137/overriding-private-methods-in-java – CollinD Jan 22 '16 at 03:35
  • 2
    you are hiding and not overriding. – Rahul Jan 22 '16 at 03:37
  • 5
    In addition to not be visible outside the type (and perhaps more relevant to the question here), private methods are *not polymorphic* - only the method defined on the type of the expression will ever be invoked; no dynamic dispatch occurs. In the shown example, *the `t` expression is of type `B`* and thus `t.don()` will *always* be invoking B's `don`. The *run-time type `A` is irrelevant* and no 'overriding' of such a private method is allowed. – user2864740 Jan 22 '16 at 03:46
  • then how [this](https://stackoverflow.com/questions/11976446/can-a-private-method-in-super-class-be-overridden-in-the-sub-class) works even the subclass object is assigned to subclass reference it still calls parent class private method – amarnath harish Jun 08 '18 at 07:35
  • More than the accepted answer, the comment from @user2864740 solves the real ambiguous behaviour. – iCantC May 19 '19 at 17:13

5 Answers5

27

You cannot override a private method. It isn't visible if you cast A to B. You can override a protected method, but that isn't what you're doing here (and yes, here if you move your main to A then you would get the other method. I would recommend the @Override annotation when you intend to override,

class A extends B {
    @Override
    public void don() { // <-- will not compile if don is private in B.
        System.out.println("hoho public");
    }
}

In this case why didn't compiler provide an error for using t.don() which is private?

The Java Tutorials: Predefined Annotation Types says (in part)

While it is not required to use this annotation when overriding a method, it helps to prevent errors. If a method marked with @Override fails to correctly override a method in one of its superclasses, the compiler generates an error.

Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • Thank you Elliott, but how the main function can use t.don() while it is a private method inside the class B – basel man Jan 22 '16 at 07:33
  • 1
    @basel Because it is **in** class `B`. Every function **in** class `B` can access the private methods in class `B`. – Elliott Frisch Jan 22 '16 at 13:24
  • @ElliottFrisch But using `@Override` should give a compile-time error, right? We are trying to override a `private` method. (It is a genuine question and I am not trying to correct you :)) – Kaushik Nov 01 '21 at 18:52
  • 1
    @Kaushik `private` methods are not inherited, so you **can't** override them. Correct. Using the annotation when you intend to `Override` will cause a compilation error when you do not in fact `Override` a method. Which was entirely my point. – Elliott Frisch Nov 01 '21 at 20:26
7

is this because the main function is in the same class as the method "don"

No, it's because A's don() is unrelated to B's don() method, in spite of having the same name and argument list. private methods are hidden inside their class. They cannot be invoked directly by outside callers, such as main method in your case, because they are encapsulated inside the class. They do not participate in method overrides.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
6

No, a private method cannot be overridden since it is not visible from any other class. You have declared a new method for your subclass that has no relation to the superclass method. One way to look at it is to ask yourself whether it would be legal to write super.func() in the Derived class.

Nitin Dhomse
  • 2,524
  • 1
  • 12
  • 24
  • Private methods **can** be visible from other classes in very specific scenarios. It is erroneous to convolute visibility with inheritance because they don't always match up. – Kröw Jul 24 '19 at 06:29
  • @Kröw : Please update your knowledge, you can not call or override the private method directly from outside class, indirectly you can call it from public method declared in the same class and that public method can be called from the outside, but that's still indirectly, indirectly everything is possible! ..........be specific! – Nitin Dhomse Jul 26 '19 at 03:50
  • Private methods *can* be called directly from a nested class. – Kröw Jul 27 '19 at 01:53
4

You can't override a private method, but you can introduce one in a derived class without a problem. The derive class can not access the private method on the ancestor.

Since t is a on object of type B, calling don() method will invoque the method defined at B. It doesn't even know that there is a method named also don() at class A

Manuel Vieda
  • 296
  • 5
  • 12
4

private members aren't visible to any other classes, even children

You can't override a private method, but then again, you can't call it either. You can create an identical method with the same name in the child however.

public class A
{
    private int calculate() {return 1;}
    public void visibleMethod()
    {
        System.out.println(calculate());
    };
}

public class B extends A
{
    private int calculate() {return 2;}
    public void visibleMethod()
    {
        System.out.println(calculate());
    };
}

If you call A.visibleMethod() it prints out 1.

If you call B.visibleMethod() it prints 2.

If you don't implement the private calculate() method in B, it won't compile because the public method that calls it can't see the private method in A.

Jim W
  • 492
  • 2
  • 11