简体   繁体   中英

Private Method overriding in java

I am trying to understand the method overriding in java. Understood that private methods cannot be overriden.

public class Superclass 
{
    private String name;

    Superclass(String name) {
        this.name=name;
    }

    private void printName(String name) {
        System.out.println("This is a Superclass output"+name);
    }
}

public class Subclass extends Superclass
{
    Subclass(String name) {
        super(name);
    }

    public void printName(String name) {
        System.out.println(name);
    }   
}   
public static void main (String[] args) {
    Superclass sb = new Subclass("Superclass");
    //System.out.println(sb.getClass().getName());
    sb.printName("this is super class variable");
}

I am trying to execute this snippet of code and the output: "This is a Superclass outputthis is super class variable"

please help me understand to which class does object sb actually refer to. and the output I see when the printName is public in the superclass is:

"this is super class variable"

also please help me understand why sb is pointing to two different class depending upon modifiers private and public.

Overriding is a run time (Dynamic) polymorphism. We can not override private methods. So private method uses static binding. A static bound method isn't associated with a particular object but rather is called on Type (class in Java).

When we make parent class method to public, dynamic binding takes place. At the run time, the type of the object determines which method is to be executed.

Superclass sb = new Subclass("Superclass");

Here the Superclass Reference variable sb will search for the Superclass Object in Subclass Object and It will find it , as it is there since Subclass extends Superclass .

sb.printName("this is super class variable");

Here since sb is pointing to the Subclass object, so if there is an overridden method it will execute that method.

But

If there is no overridden method, it will always execute the Superclass method since reference type is Superclass .

Ref : http://www.codejava.net/java-core/the-java-language/12-rules-of-overriding-in-java-you-should-know

Why parent class type reference variable having reference to child class object can't access child class's Methods

You cannot access a private method outside its class.

Have a look at the following table * :

            | Class | Package | Subclass | Subclass | World
            |       |         |(same pkg)|(diff pkg)| 
————————————+———————+—————————+——————————+——————————+————————
public      |   +   |    +    |    +     |     +    |   +     
————————————+———————+—————————+——————————+——————————+————————
protected   |   +   |    +    |    +     |     +    |         
————————————+———————+—————————+——————————+——————————+————————
no modifier |   +   |    +    |    +     |          |    
————————————+———————+—————————+——————————+——————————+————————
private     |   +   |         |          |          |    

+ : accessible
blank : not accessible

src

So if you want to print "This is a Superclass outputthis is super class variable" you have to make printName() of your super class at least package private (= no modifier).

to your second question:

please help me understand to which class does object sb actually refer to. and the output i see when the printName is public in the superclass is :

"this is super class variable"

java automatically takes the function of the subclass because your created an instance of it at:

Superclass sb = new Subclass("Superclass");

First thing first, You should explore more by yourself so you would not need to ask such question when your output itself answered the question. Your question is about which object rather than why is this behavior. Well to answer your question. Consider below 2 senarios

Case 1: Super super=new Super();
Case 2: Super superSubclass=new Subclass(); //extends Super and instance refered by Super Super superSubclass=new Subclass(); //extends Super and instance refered by Super
Case 3: Subclass subclass=new Subclass();// Referenced by own

Case1: This class does not aware about any other implementations on the earth so all it can access are its own declared methods inside Super class ( ALL means ALL including Private ). So no confusion ever just look at only this class.

Case2: As per statement Subclass is extended implementation of Super and instance is created referencing by Super. in this case, superSubclass can access overridden methods in extended implementation in addition to CASE 1. means all method of SUPER + overridden method in SUBCLASS

Case3: Consider it like case 1. Reference is same as it's instance, it can access its ALL methods + non private methods of it's subclass.

I answered this in the same tone of your question, tried to clear your confusion. But I think main thing what you need to understand is WHY this behavior which will eventually clear your concepts. However as I see you are beginner so you will learn once you start predicting outputs like I mentioned above.

Cheers !

Because the invocation of private method is determined at compile-time. (By the way constructor and super method are also determined at compile-time).

I will explain it by bytecode.
First is the source code:

public class Q47069297 {
  public static void main(String[] args) {
    SuperClass sc = new SubClass();
    sc.print();
  }

  private static class SuperClass {
    private void print() {
      System.out.println("super");
    }
  }

  private static class SubClass extends SuperClass {
    private void print() {
      System.out.println("sub");
    }
  }
}

And the bytecode of the invocation of SuperClass.print :

10  invokestatic xdean.stackoverflow.java.Q47069297$SuperClass.access$1(xdean.stackoverflow.java.Q47069297$SuperClass) : void [21]

What's wrong? we called print but there is SuperClass.access$1 !
Let's go to SuperClass 's bytecode and find access$1

  static synthetic void access$1(xdean.stackoverflow.java.Q47069297.SuperClass arg0);
    0  aload_0 [arg0]
    1  invokespecial xdean.stackoverflow.java.Q47069297$SuperClass.print() : void [32]
    4  return
      Line numbers:
        [pc: 0, line: 10]

Wow, there really a method, a synthetic method named access$1 . So we find the private method invocation out of the class itself is just a cheat of java compiler. It generate a package-friendly static method in the class and invoke it. So the source code should be:

SuperClass sc = new SubClass();
SuperClass.access$1(sc);// sc.print();

It doesn't call SubClass because it is indeed a static method invocation.

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