我们都知道子类继承父类时,会继承所有的成员变量和成员方法,前提是有访问权限,若为private修饰或者default修饰却在不同包就不会继承(这里有争议的一点是有人说是时继承了但不能访问,有人说根本就没继承,博主也没有研究过,这个问题不重要,反正不能调用就对了)。先看下面一个正常的例子,熟悉一下正常的继承特性

class Parent{
    public int age=30;
    public void print1(){
        System.out.println("parent print1:"+age);
    }
    public void print2(){
        System.out.println("parent print2:"+age);
    }
}
class Child extends Parent{
    //public int age=10;
    @Override
    public void print2(){
        System.out.println("child print2:"+age);
    }
}
public class ParentChildTest {
    public static void main(String[] args) {
    Parent p=new Parent();
    Child c=new Child();
    Parent pc=new Child();
    System.out.println("p.age"+p.age);
    System.out.println("c.age"+c.age);
    System.out.println("pc.age"+pc.age);
    System.out.println();
    System.out.print("p. ");
    p.print1();
    System.out.print("p. ");
    p.print2();
    System.out.println();
    System.out.print("c. ");
    c.print1();
    System.out.print("c. ");
    c.print2();
    System.out.println();
    System.out.print("pc. ");
    pc.print1();
    System.out.print("pc. ");
    pc.print2();
    }
}

p为父类对象,c为子类对象,pc为一个用子类实例化的父类对象(实现向上转型)
输出结果:

p.age30 
 c.age30 
 pc.age30 
 p. parent print1:30 
 p. parent print2:30 
 c. parent print1:30 
 c. child print2:30 
 pc. parent print1:30 
 pc. child print2:30可以看到, 
 c. parent print1:30 
 c. child print2:30


子类继承了父类的age属性和print1方法,并且覆写了print2方法,这两个方法都调用了age属性,print1调用的自然是父类中的age属性,而print2中调用的是父类中的属性还是子类中继承下来的属性暂且不去深究,因为这两个属性根本上来说是一样的。

下面开始进入重名这个问题
我们把上述代码中的注释打开

class Parent{
    public int age=30;
    public void print1(){
        System.out.println("parent print1:"+age);
    }
    public void print2(){
        System.out.println("parent print2:"+age);
    }
}
class Child extends Parent{
    public int age=10;
    @Override
    public void print2(){
        System.out.println("child print2:"+age);
    }
}

可以看到父类子类里面都是一个叫age的属性,那么现在的输出结果会怎么样呢?

p.age30 
 c.age10 
 pc.age30p. parent print1:30 
 p. parent print2:30c. parent print1:30 
 c. child print2:10pc. parent print1:30 
 pc. child print2:10

首先通过 对象名.成员变量 的方式直接取得的属性以类名为原则。若是Parent类,就取得该类中的属性,反之亦然。从pc.age30可以看出来子类实例化向上转型并没有覆盖原有父类的属性,所以可以得出继承无法覆盖成员变量,只能覆盖方法。父类与子类的成员相互独立,相互隐藏。至于c中调用从父类继承的print1方法并没有指向自己类中的age,而指向父类中的age,不难解释。因为没有覆写的方法,从父类继承下来,可看作编译器会自动帮你加上如下代码(以print1举例)

class Child extends Parent{
    public int age=10;
    @Override
    public void print2(){
        System.out.println("child print2:"+age);
    }
    public void print1(){
        super.print1();
    }
}

自动去调用了父类中的print1,所以自然也指向了父类中的age。

总结,继承只能覆盖方法,而不能覆盖成员变量,若有同名变量,则相互独立,直接获取时依据对象类型,调用时依据方法定义在哪个类中。