9

I have confusion about using private methods in inheritance, for example:

public class A {
    private void say(int number){
        System.out.print("A:"+number);

    }
}

public class B extends A{
    public void say(int number){
        System.out.print("Over:"+number);
    }
}

public class Tester {
    public static void main(String[] args) {

        A a=new B();
        a.say(12);

    }
}

Based on the codes above, I am confused about the inheritance of private method, is the private method inherited from class A to B? Or the say methods in both classes are totally unrelated? As the code has error when it is running in main() method, it seems like class B cannot invoke the private method from class A.

bbalchev
  • 827
  • 1
  • 9
  • 19
pei wang
  • 295
  • 2
  • 8
  • 17

6 Answers6

23

If you want a subclass to have access to a superclass method that needs to remain private, then protected is the keyword you're looking for.

  • Private allows only the class containing the member to access that member.
  • Protected allows the member to be accessed within the class and all of it's subclasses.
  • Public allows anyone to access the member.
nhgrif
  • 61,578
  • 25
  • 134
  • 173
  • thanks for your answer, now I understand that protected is the solution if I need to remain private in subclass, but when we have private instance in a superclass, we can use getter method to call it in the subclass, why the private method cannot do the same way? – pei wang Oct 19 '13 at 03:06
  • If you have a `private` member that has a `protected` or `public` getter, the getter can be used to accessed the `private` method. Why? Because the getter has `protected` or `public` visibility. – nhgrif Oct 19 '13 at 03:08
  • But for the above codes, I could not generate Getter and Setter methods for class A, as there is no private instance – pei wang Oct 19 '13 at 03:10
  • 1
    Typically, `getter` and `setter` refers to public methods that allow access to private variables. In this case, you have a `private` method. If you want to call this method, there are two things you can do. You can change the method's visibility to `protected` or `public`, or you can do something similar to a `getter`, like this: `public void getSayMethod(int someNum) { say(someNum); }` It makes no sense to me... but you could do it. – nhgrif Oct 19 '13 at 03:13
  • Hi nhgrif, by using the getter method, I tried A.a=new A(); and A.a=new B(); they both prints,A:12. Does it mean no matter which object I use (new A or new B), it always prints the same thing – pei wang Oct 19 '13 at 03:30
  • Try `B b = new B(); b.say(12);`. Also, try more descriptive class and variable names. – nhgrif Oct 19 '13 at 03:32
2

There are two things going on here.

First, keep in mind the distinction between the type of the reference and the type of the object.

When you say

A a = new B();

the reference is a of type A, but the object is of type B. So when you call a.say(12);, you are looking at B from the A API/interface/perspective.

Second, because you are looking at B from the A perspective, you are going to get an error because A has no public method called say(). Of course B does, but remember you are treating B as an A. When you do that, you lose any ability (unless you cast later, but don't worry about that for now) to reference those B methods that A doesn't know about.

In the end, B actually never inherits say() from A since it can't see it in the first place, and A has no public method say() for anyone to access.

Now if you want to really have some fun, make say() protected in A and private in B and see what happens.

Vidya
  • 29,932
  • 7
  • 42
  • 70
  • Since say() is an instance method here, shouldn't A a = new B(); be calling the say() method in B due to polymorphism (late binding)? – Hello World Jul 19 '20 at 17:17
1

The reason you are getting the error is because say(int) is private. This has nothing to do with inheritance. You can only call a private member method in its definition class.

To answer your inheritance question, B.say() is a different method - it isn't even overriding method A.say() because derived classes can't inherit private methods from its base class. Only protected and public methods/variables can be inherited and/or overridden.

Lews Therin
  • 10,907
  • 4
  • 48
  • 72
  • Hi Lews, thank you for your reply, I am think if we have private instances in a superclass, we can use getter method to invoke it in its subclass, so if we have private methods in a superclass, is there any solution to invoke them in the subclass? – pei wang Oct 19 '13 at 03:03
  • Subclasses can access `protected` and `public` members. You can make a `private` variable with a `public` or `protected` setter and getter which the subclasses can use to access the `private` variable. – nhgrif Oct 19 '13 at 03:04
  • If they are private methods/instances then there shouldn't be a reason to invoke that method outside its class. Trying to do so it is code smell. But having said that you can always created public getter and setter in the base class to invoke the private method.. but then there is a reason why encapsulation was invented. – Lews Therin Oct 19 '13 at 03:04
0

Private means you can Only access it in that class an no where else.

Ducksauce88
  • 640
  • 3
  • 12
  • 26
0

Subclasses can only invoke or override protected or public methods (or methods without access modifiers, if the superclass is in the same package) from their superclasses. private methods stay in the class in which they're declared and aren't visible to any other class, no matter how it's related.

Josh
  • 1,563
  • 11
  • 16
-1

Private methods are inherited in sub class ,which means private methods are available in child class but they are not accessible from child class,because here we have to remember the concept of availability and accessibility.