我正在努力理解Variables Shadowed Methods Overriden使用Java继承概念。
案例1:
class Car{
public int gearRatio = 8;
public String accelerate() { return "Accelerate : Car"; }
}
class SportsCar extends Car{
public int gearRatio = 9;
public String accelerate() { return "Accelerate : SportsCar"; }
public static void main(String[] args){
Car c = new SportsCar();
System.out.println( c.gearRatio+" "+c.accelerate() );
}
}
输出:8加速:跑车。
案例2:
public class TestClass{
public static void main(String args[ ] ){
A o1 = new C( );
B o2 = (B) o1;
System.out.println(o1.m1( ) );
System.out.println(o2.i );
}
}
class A { int i = 10; int m1( ) { return i; } }
class B extends A { int i = 20; int m1() { return i; } }
class C extends B { int i = 30; int m1() { return i; } }
输出:30,20
因此,如果我理解正确,除非明确调用子类变量,否则总是调用超类变量。但对于调用子类重写方法的方法则相反,除非显式调用超类。
我认为变量和方法应该相同,或者在创建具有相同变量的子类时应该存在编译错误。
有人可以解释这是否正确以及为什么java会像这样工作。
答案 0 :(得分:13)
我认为变量和方法应该相同,或者在创建具有相同变量的子类时应该存在编译错误。
嗯,这根本不是Java的工作方式。
变量不以多态方式处理 - 没有“覆盖”变量的概念。但是,的方法以多态方式处理。 行为可以是专门的,但不是州。
请注意,如果您的变量是私有的,因为它们几乎总是应该是,那么情况永远不可见。
答案 1 :(得分:1)
在java中没有Instance variable overriding concept
,变量不像methds那样是多态的。
所以在你的情况下,如果你使用:
Car c = new SportsCar(); // c is Object reference of type Car
System.out.println( c.gearRatio+" "+c.accelerate() );
c.gearRatio
指的是Car
和not from SportsCar
中的gearRatio。对于方法c.accelerate()
,方法在SportsCar
中被覆盖,并且它是SportsCar
对象,因此调用SportsCar.accelerate()
。
public static void main(String args[ ] ){
A o1 = new C( ); // object reference is of type A and object is C
B o2 = (B) o1; // object of C can be type casted to B as B is parent to C
System.out.println(o1.m1( ) ); // C.m1() will be called.
System.out.println(o2.i ); // o2 is type B, so B.i will be printed
}