1
public class A {
    public int a = 10;
    public void show() {

    }
}

public class B extends A{
    public int a = 20;
    public int b = 10;

    @Override
    public void show() {
        System.out.println(this.a);
    }

    public static void main(String[] args) {
        A a = new B();
        a.show();
        System.out.println(a.a);
    }
}

See the code above, I use parent class A references to point to the child class B object (A a = new B()), But when I print a.a(System.out.println(a.a)) in the main method, it prints 10 because the member variable a is assigned a value of 10 in the parent class A. But when I print this.a(System.out.println(this.a)) in the show method, which is rewritten in the subclass, the show method prints this.a (System.out.println(this.a)), it prints 20 and I'm confused. I think the result should be the same. You can see the output as shown below:

20
10

Thanks in advance!

helloWorld
  • 35
  • 7

2 Answers2

0

In java only methods are overridden, not variables. So, parent classe's variables won't be overridden by child's classes variable. It's a design decision in java. And one of the concern is that the parent classes methods can perform without worrying about child's classes variables...i.e. it helps in not breaking parent classes code...

An example could be like below:

public class Parent {
  String someVar; // note this: it is "String" type
  String getSomeVar() {
  }
}

public class Child extends Parent {
  int someVar; // same name but different type, this would break the code if
  // java permit "variable overriding" feature
}

You can clearly see that parent's type and child's type are different. I guess, you can understand now why variable overriding would be dangerous...

Update:

@helloWorld, After reading the last comment you've made, it looks like, you're misunderstanding the idea of overriding.

Specially, I've prepared an example for you. Read the following code with comments:

class A {
    public int a = 10;

    public void show () {
        System.out.println("Inside A: " + this.a);
    }
}

class B extends A {
    public int a = 20;
    public int b = 10;

    @Override
    public void show() {
        System.out.println("Inside B: " + this.a);
    }
}
B b = new B();
A a = b;

b.show(); // prints "Inside B: 20", it should print "20", so it's okay
a.show(); // prints "Inside B: 20", so, method in 'A' is overrided by class 'B', cause, in normal definition it should print "10"

System.out.println("value of b.a: " + b.a); // prints "value of b.a: 20", it should print '20', so it's okay
System.out.println("value of a.a: " + a.a); // prints "value of a.a: 10", it is not overrided by class 'B', but notice 'a.show()' method was overrided

So, I guess, you've understood, that overriding means: when use something(a method/variable) by parent/super class's reference but get the behavior defined in child class's while parent/super class's implementation of that particular method/variable is present, is known as overriding...

You may also read this.

And about this:

this is bound to an object. And it's always used to access only that particular class's scope i.e. the variables/methods declared in that class. So, to access parent within child you need to use super.

reyad
  • 1,392
  • 2
  • 7
  • 12
  • I know only method are overridden, not variables in java.In other words, i think variable a in class A has nothing to do with variable a in B.But when i use method show (`System.out.println(this.a)`) in main,I think 'this' shoud be reference to object a of parent class A.So here should print 10 not 20. – helloWorld Aug 12 '20 at 07:53
  • @helloWorld, No, as the method is overridden, the passed `this` would use `B` classes `a` variable...but of course you have already got it...you can access `A`'s `a` variable using `super`...hope it clears things up... – reyad Aug 12 '20 at 07:58
  • @reyadThank you very much.I probably understand what you mean,But I'm still a little confused.Because in `A a = new B()`,I think a should use variable `a` in class A not in class B.In method main,you could see `System.out.println(a.a)` will print 10(`public int a = 10` in class a). – helloWorld Aug 12 '20 at 08:25
  • @helloWorld, tell me `what is this pointer`...which object `this` pointer targets...in a overrided method scope `this` pointer targets the `child` and `this` exists only in `non-static` methods...so, `a` may be casted to `A` but it is created using `B`... that's how `java` resolves the problem of targeting proper variable in `parent scope` and `child scope`...that's how java works...now we can't change it...it's java's philosophy...its what java do..:D – reyad Aug 12 '20 at 09:30
  • ,well,thank you again.Maybe the way I use violate java's philosophy, I think I should give up the way to avoid Unnecessary trouble. – helloWorld Aug 12 '20 at 10:23
  • Today I read again the answer you gave about why variables can't be overridden.If `String someVar` in parent class can be overridden by `int someVar` in child class.When a subclass object(`Child c = new Child()`) calls the getSomeVar method,the method will return a int variable(Assuming variables can be overridden),but the return value type of `getSomeVar` is String. – helloWorld Aug 13 '20 at 02:16
  • @helloWorld, I guess, the discussion would clear your mind...take a look... – reyad Aug 13 '20 at 04:14
0

I believe that the best practice for Polymorphism is not by overriding the variable, because it will cause a fatal error. If your question is about "Polymorphism: how-to," this answer may help:

    //create class A, as you did:
    public class A {
        public int a; //note that we do not initialize the value here
        public void show() {
    
        }
    }

    //extend class B from class A, as you did:
    public class B extends A {
        public int b; //note that we only need to declare variable b

        @Override
        public void show() {
            System.out.println(this.a);
        }
    }

    //in the main class:
    public static void main(String[] args) {
        B a = new B();
        a.a = 20;
        a.b = 10;
        a.show();
    }
Bram
  • 16
  • 4