简体   繁体   中英

Why can methods be overridden but variables can't?

Code:

 public class ClassTest {

      public static void main(String args[]) {
           test1 cc = new test2();
           System.out.println(cc.A);
           System.out.println(cc.B);
           cc.method1();
           cc.method2();
      }

 }

 class test1 {
      static int A = 2;
      int B = 5;

      void method1() {
           System.out.println("Inside method 1 test1");
      }

      static void method2() {
           System.out.println("Inside method2 test1");
      }
 }

 class test2 extends test1 {
      static int A = 4;
      int B = 6;

      void method1() {
           System.out.println("Inside method 1 test2");
      }

      static void method2() {
           System.out.println("Inside method 2 test2");
      }
 }

OUTPUT:

2

5

Inside method 1 test2

Inside method2 test1

Question:

Why are only the methods overridden, but the variables remain unchanged?

Does this behaviour have a name? (like "overriding" for methods)

Overriding a method means let the same method call execute another method body (in the child class).

For a variable "overriding" is unnecessary: you can overwrite the variable's value.

Declaring a variable in the child class with the same name hides the parent classes variable and introduces an additional field.

For methods to be overridable a special mechanism is needed so that the place in the code may call the method that the actual class of the object specifies. This as opposed to accessing a field.

What happened here was that you've used type1 reference to point to an instance of test2 . You can do this because test2 is a type of test1 - this is called Polymorphism .

test2 is derived from test1 , so when you create an object of type test2 you will basically have two objects created, test2 and test1 (which will not reside in the heap as an autonomous object).

The JVM will access the fields of the object from its reference (because Java is a statically typed language).

So, although, test2 hides both fields of test1 , when trying to access them from the test1 reference Java goes automatically to test1 .

That's about it regarding the fields.

When dealing with methods we have a more complicated issue. Methods are overridden , thus, when the method table is built, the methods of test2 override the methods of test1 . But, static methods are not instance methods.

Thus, when trying to access the static method method2 , of test2 from the reference of test1 , you are "abusing" the code. What you should be doning is calling test1.method2() or, if you want to access the static method of test2 you should use test2.method2() .

Hope I explained it well enough...

在上面的示例中,您正在创建基类的引用,它将获取值A = 2,B = 5并且它也将分配内存。因此,当覆盖到派生类时,基类变量隐藏派生类变量值,这就是为什么它可以不在派生类中重写。

In line: System.out.println(cc.A);
This is not the correct way for calling static member, you should always use class name, eg: System.out.println(test1.A);

As per the Java specifications, the instance variables are not overridden from a super class by a sub class when it is extended.
Whether the variable be static or nonstatic. Only methods can be overriden. That's why the output of cc.A & cc.B is from test1 class

For Method Overriding:
The code cc.method1(); here overrriding takes place, the object type(ie the instance of class) actually determines which method is selected at run time, by this object declaration of new test2() in this code: test1 cc = new test2();
The compiler first checks the method in test1 class and then it checks in method in text2 class, if all the signatures (arguments, return types etc) are same then it invokes the sub class method since it is overriding the base class method, because actual object is of class test2 .

For Static methods: Static methods cannot be overridden because method overriding only occurs in the context of dynamic (ie runtime) lookup of methods.
Static methods (by their name) are looked up statically (ie at compile-time).
thats why the output is from class test1 .

For "static methods" in Java the exact method to call is determined at compile time.
You explicitly specify the name of the class whose static method you want to execute

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM