-3

I am wondering why this.(...) has no effect in this scenario. The following is a Task of my Exam:

class PARENT {
    public int x;
    public PARENT(int a)    {this.x = a;}

    public int getX()   {return this.x;}
    public int getY()   {return this.getX();}
}

class CHILD1 extends PARENT {
    public int x;
    public CHILD1(int b) {super(b); this.x = 2 * b;}
}

class CHILD2 extends PARENT {
    public CHILD2(int c)    {super(c);}

    public int getX()   {return 5;}
}

public class ThisTestMain {
    public static void main(String[] args)  {
        PARENT PP = new PARENT(10);
        PARENT PC1 = new CHILD1(100);
        PARENT PC2 = new CHILD2(1000);
        System.out.println(PP.getY());
        System.out.println(PC1.getY());
        System.out.println(PC2.getY());

        CHILD1 CC = new CHILD1(10);
        System.out.println(CC.getY());
    }
}

The output is:

10
100
5
10

My question now is why at System.out.println(PC1); the output is NOT 200. Because when I debug the code in IntelliJ I can see that this has the reference CHILD1@799 and the Object can see the values x and PARENT.x.

At this point why is getX() choosing PARENT.x and not CHILD1.x?

By overriding methods this has also no effect. In this case for example System.out.println(PC2); uses always the getX() in CHILD2, no matter if you write in the getY() Method return this.getX(); or return getX();.

Can someone summerize the system behind that? Maybe also considering super? Thanks!

Debug in IntelliJ

2 Answers2

1

CHILD1 defines a new field named x that shadows the field x in PARENT. Remove the field. Like

class CHILD1 extends PARENT {
    // public int x;
    public CHILD1(int b) {super(b); this.x = 2 * b;}
}
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • Thanks, but I´m wondering why the "int x" in CHILD1 does NOT shadow the "int x" in PARENT. Especially when I take the Self Reference from CHILD1 with "this.x" –  Feb 18 '20 at 23:08
  • Because instance variables are not overridden as methods are. CHILD1 methods would access CHILD1's `x`, but PARENT's methods will access PARENT's `x` - see https://stackoverflow.com/questions/12086298/why-is-an-instance-variable-of-the-superclass-not-overridden-by-a-subclass for more details. – racraman Feb 18 '20 at 23:25
  • 1
    You have two `int x` variables in your example, in `CHILD1`. For the `PARENT` `int x` you would use `super.x` (but better not to shadow the fields anyway, that "breaks" inheritance). – Elliott Frisch Feb 18 '20 at 23:26
  • Thanks @racraman for the link, now I understand the situation. @Elliott Frisch I still dont get your point, because obviously you cannot access `CHILD1.x` from `PARENT.getX`, because the Method only sees the Variables in his own class. You could only access it by overriding the Method in CHILD1, so `super.x` is redundant. (`this.x` also) –  Feb 19 '20 at 14:26
  • "the Method only sees the Variables in his own class. " - not quite. Methods can see variables in their own class AND ALSO protected/public variables in the superclasses. That means CHILD1 methods can access PARENT1 variables, but it's just in this case the PARENT1 variable is shadowed by a CHILD1 variable of the same name - hence the CHILD1 method can use the `super.x` syntax to access the PARENT1 variable. It is also worth emphasising NEVER name variables such that they shadow superclass variables like this; AVOID this situation in actual projects :) – racraman Feb 20 '20 at 13:06
0

In CHILD1 you have no overridden methods.

So when you call getY() it then calls getX() from the PARENT. The method from the PARENT has no idea about variables in its child classes.

You must override method getX() in CHILD1 to get access to the variable CHILD1.x.

OleksiiMLD
  • 80
  • 1
  • 7
  • Thanks! So inherited and not overriden Methods generally only have access to the Parent Class´ Variables (Fields)? –  Feb 18 '20 at 23:30