user3903342
user3903342

Reputation:

Java - Access Modifiers and Which Methods Are Called

So I have the following two cases:

Case 1:

public class Person {
   private String name = "Person";
   private String getName() {
      return name;
   }

   public void printName() {
      System.out.println( getName() );
   }
}

public class Student extends Person {
   private double gpa = 0;
   private String getName() {
      return “Student”;
   }
}

public class Driver {
   public static void main(String[] args){
      Person p = new Person();
      Student s = new Student();

      p.printName();  // “Person”
      s.printName();  // “Person”
   }
}

Case 2:

public class Person {
   private String name = "Person";
   public String getName() {
      return name;
   }

   public void printName() {
      System.out.println( getName() );
   }
}

public class Student extends Person {
   private double gpa = 0;
   public String getName() {
      return “Student”;
   }
}

public class Driver {
   public static void main(String[] args){
      Person p = new Person();
      Student s = new Student();

      p.printName();  // “Person”
      s.printName();  // “Student”
   }
}

Case 2 makes the most sense (it's intended behavior).

But why does Case 1 not output the same as Case 2 ("Person" instead of "Student")?

From what I understand, non-static calls implicitly use this. And from this SO post, this and super don't "stick". Thus, for the first case, getName() should use Student's implementation as this refers to the Student instance (regardless of access modifiers). But that doesn't appear to be the case..

Thanks in advance!

Upvotes: 2

Views: 90

Answers (2)

dave
dave

Reputation: 11975

In each case Person.printName() calls getName().

In Case 1, the only visible version is Person.getName(), hence that is called for both Person and Student.

In Case 2, Student.getName() overrides Person.getName(), hence the former is called.

So the different visibility applied to getName() influences the outcome. When it's public (or protected), it can be over-ridden and the method called will depend on the object. When it's private, there is no over-riding and Person.getName() is always called.

Upvotes: 0

Jacob G.
Jacob G.

Reputation: 29680

For Case 1, Student#getName does not override Person#getName, as the methods are private, meaning they are not accessible to other classes. Because Student#getName implicitly overrides Person#getName (since both are now public), Student is printed in Case 2.

Upvotes: 2

Related Questions