-1

Parent and child class having same variable - "name," which has been accessed through inherited method - getName() in Parent Class

class A {
    String name = "A";
    String getName() {
        return name;
    }
    String greeting() {
        return "Class A";
    }
}

class B extends A {
    String name = "B";

    String greeting() {
        return "Class B";
    }
}

public class Client {
    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        System.out.println(a.greeting() + " has name " + a.getName());
        System.out.println(b.greeting() + " has name " + b.getName());
    }
}

Output:

Class A has name A
Class B has name A

In the above snippet, b.getName() returns the output as "A" though accessed using child class reference. Can someone pls explain this?

Note: I have visited this link already - Overriding member variables in Java ( Variable Hiding), where in that link, the variable is accessed directly using the reference. In the given code snippet above, it has been accessed through the inherited method, which produced the output using the parent class variable, though called via the Child Class reference and Child Class Object.

  • What exactly you don't understand? This is behaving as expected. – lealceldeiro May 29 '19 at 14:35
  • because is called method `getName` of class `A` which has no access to fields in class `B` – Alex Salauyou May 29 '19 at 14:35
  • 3
    You need to realize that the `name` variables defined in `A` and `B` are completely different variables. You could define `name` in `B` as of a different type or class and it would change nothing to how your code works. Class `A` has no knowledge of (or any way to reference) `name` defined in `B`. Because `getName()` is defined in `A` you get `A`'s knowledge of `name`. – Alain May 29 '19 at 14:40
  • Just to add, if you want to have "Class B has name B" as a result, drop the 'name' attribute of B and have 'name' assigned with "B" in the constructor. This is possible because 'name' in A is not private – Jayr May 29 '19 at 15:29
  • Thanks much Alain ! Also the section Example 8.3.1.1-3. Hiding of Instance Variables in https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#d5e10238 - made it clear. I was confused as by inheritance, since the reference points to class B, so was expecting B's variable to be called. Variables hiding concept cleared it. – Janani Sampath Kumar May 29 '19 at 16:10

1 Answers1

0

Reference - https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#d5e10238 Section - Example 8.3.1.1-3

Class B now has two variables,

  • String name = "A" --> from class A
  • String name = "B" --> from class B (but this will hide the above one and can't be called directly)

Assume the below class references:

A a = new A();
B b = new B();
  • String name = "A" can be obtained by: super.name or a.name or a.getName()
  • String name = "B" can be obtained by: b.name or overriding the method getName() in class B

With the given code snippet in question,

  1. We are calling inherited method getName() from parent class A in class B
  2. This inherited method is aware of the instance variable "name" in class A only
  3. Hence it points to String name = "A" in class B, as class B contains both and the output is "A" here, though the class reference and object is of type 'B'