0

Guys, My question is very simple. Look at the following code:

    public class Test {
            public static void main(String[] args){
            SubTest st = new SubTest();
            st.sayName();
            }
    }

    class BaseTest{
        String name= "BaseTest"; 

        void sayName(){
            System.out.println(getClass());
            System.out.println(this.name);
        }
    }

    class SubTest extends BaseTest{
        String name= "SubTest";


    }

Output:

xxx.xxx.SubTest

BaseTest

I know the methods will be inherited or overridden and the fields will be shadowed in the inheritance. So it is supposed that the value of subclass is printed, not that of baseclass. However, there must be something I dropped. Hope someone can tell me. Thanks.

franksunnn
  • 147
  • 2
  • 9
  • http://stackoverflow.com/questions/685300/is-there-a-way-to-override-class-variables-in-java – smk Nov 22 '13 at 19:13
  • 1
    http://stackoverflow.com/questions/8647248/hidden-fields-though-inheritance – Taylor Nov 22 '13 at 19:14
  • 1
    *I know the methods will be inherited or overridden and the fields will be shadowed in the inheritance* this is called [Field Hiding](http://docs.oracle.com/javase/tutorial/java/IandI/hidevariables.html). When you talk about shadowing, you mean a method variable with the same name of the class field e.g. setters. – Luiggi Mendoza Nov 22 '13 at 19:31

2 Answers2

3

Instance variables are not subject to polymorphism as methods are. So, yes, SubTest inherits the sayName() method from BaseTest, but the method still refers to BaseTest's name variable. Note that the SubTest class now has two name instance variables.

To print "SubTest", you could override sayName():

@Override
void sayName(){
    System.out.println(getClass());
    System.out.println(this.name);
}

Here, this.name would refer to SubTest's name variable.

rgettman
  • 176,041
  • 30
  • 275
  • 357
  • Or even better, initialize `super.name` variable in the constructor of the class, no need to override the method. – Luiggi Mendoza Nov 22 '13 at 19:29
  • Saying `super.name` will refer to the superclass's `name` variable, to get around the fact that the superclass's `name` variable is hidden. – rgettman Nov 22 '13 at 19:40
1

Your method is defined in the BaseTest. It is unaware of who inherits it. it does not know that there is a SubTest class. So when you print the value, you print the value of name from the BaseTest class.

If you want to print the value of name in SubTest then you must override the method in SubTest. Since you have not overriden the method, all your calls are automatically to the inherited sayName() which, as I said, prints the name from BaseTest

Place this code in your SubTest class:

@Override
void sayName(){
      super.sayName(); // calls sayName() of the super class
      System.out.println(this.name); // prints value of name in the SubTest class
}
An SO User
  • 24,612
  • 35
  • 133
  • 221