Java继承中对成员变量和方法的处理是不同的,看如下代码:
class Base {
    
    public int count = 2;
     
    public void display() {
        System.out.println(this.count);
    }
}
class Derived extends Base {
    
    public int count = 20;
    @Override
    public void display() {
        System.out.println(this.count);
    }
    
}
public class Test {
    public static void main(String[] args) {
        
        Base b1 = new Base();  // (1)
        System.out.println(b1.count);  
        b1.display();  
        
        Derived d1 = new Derived();  // (2)
        System.out.println(d1.count);  
        d1.display();  
        
        Base b2 = new Derived();  // (3)
        System.out.println(b2.count);
        b2.display();
        
        Base b3 = d1;  // (4)
        System.out.println(b3.count);
    }
}
结果:
2
2
20
20
2
20
2分析:
编译器处理方法和成员变量的区别:
看以下代码:
class Base { int count = 2; }
class Mid extends Base { int count = 20; }
class Sub extends Mid {int count = 200; }
public class Test {
    public static void main(String[] args) {
        Sub sub = new Sub();
        Mid mid = sub;
        Base base = sub;
        
        System.out.println(sub.count);
        System.out.println(mid.count);
        System.out.println(base.count);
    }
}
结果:
200
20
2以上程序说明:sub、mid和base这3个变量指向的Java对象拥有3个count实例变量,也就是说,需要3块内存来存储它们
 当Sub sub = new Sub();这句执行完后,该对象在内存中的存储如下图所示:

内村中并不存在 Mid 和 Base 两个对象,只有一个 Sub 对象,只是这个 Sub 对象中不仅保存了在 Sub 类中定义的所有实例变量,还保存了它的所有父类所定义的全部实例变量,程序通过 Base 型变量访问该对象的count实例变量,将输出2,通过 Mid 型变量访问该对象的count实例变量,将输出20
看以下代码:
class Fruit { 
    
    String color = "unknow";
    
    public Fruit getThis() {
        return this;
    }
    
    public void info() {
        System.out.println("Fruit's info()");
    }
    
}
class Apple extends Fruit {
    
    String color = "red";
    @Override
    public void info() {
        System.out.println("Apple's info()");
    }
    
    public void accessSuperInfo() {
        super.info();
    }
    
    public Fruit getSuper() {
        return super.getThis();
    }
    
}
public class Test {
    public static void main(String[] args) {
        Apple apple = new Apple();
        Fruit fruit = apple.getSuper();
        System.out.println("apple == fruit: " + (apple == fruit));
        System.out.println("apple.color: " + apple.color);
        System.out.println("fruit.color: " + fruit.color);
        apple.info();
        fruit.info();
        apple.accessSuperInfo();
    }
}
运行结果:
apple == fruit: true
apple.color: red
fruit.color: unknow
Apple's info()
Apple's info()
Fruit's info()注意这个方法:
public Fruit getSuper() {
    return super.getThis();
}该方法尝试返回super关键字代表的内容,实际上,Java程序允许通过方法return this;返回调用该方法的Java对象,但不允许直接return super或者直接将super当成一个引用变量来使用,接下来会深入的分析这些语法规则
Apple apple = new Apple();
Fruit fruit = apple.getSuper();apple == fruit 返回true,说明通过apple.getSuper()返回的是该Apple对象本身,只不过它的声明类型或者编译时类型是Fruit,所以通过 fruit 访问实例变量color,得到的是"unknow",而通过fruit调用info(),实际上就是调用apple对象的info()方法,调用accessSuperInfo();时使用super限定调用Fruit类的info()方法,所有该info()方法才真正表现出Fruit类的行为。
通过以上分析得出结论:super关键字本身并没有引用任何对象,它甚至不能被当成一个真正的引用变量,所以以下代码,编译就会报错:
super = new Fruit();
super = apple;
super = fruit;总结:
类变量属于类本身,因此关于父类和子类的类变量的继承关系并不复杂,看如下代码:
class Base { public static int count = 20; }
class Sub extends Base { 
    
    public static int count = 200; 
    
    public void info() {
        System.out.println("Sub's count = " + count);
        System.out.println("Base's count = " + Base.count);
        System.out.println("Base's count = " + super.count);
    }
    
}
public class Test {
    public static void main(String[] args) {
        Sub sub = new Sub();
        sub.info();
    }
}
结果:
Sub's count = 200
Base's count = 20
Base's count = 20总结: