Java继承重写实例变量

Java继承重写实例变量,java,oop,Java,Oop,我正在学习java。我对继承权有疑问。当子类扩展父类且父类具有引用父类中声明的实例变量的方法时。但是子类dint重写了这个方法,并且声明了与父类同名的实例变量。在这种情况下,将引用子实例变量或父实例变量。下面是代码片段 class Parent { int a; Parent() { System.out.println("in Parent"); a = 10; } void method() {

我正在学习java。我对继承权有疑问。当子类扩展父类且父类具有引用父类中声明的实例变量的方法时。但是子类dint重写了这个方法,并且声明了与父类同名的实例变量。在这种情况下,将引用子实例变量或父实例变量。下面是代码片段

class Parent {
    int a;
    Parent() {
        System.out.println("in Parent");
        a = 10;
    }
    void method() {
        System.out.println(a);
    }
}
class Child extends Parent {
    int a;
    Child() {
        System.out.println("in Child");
        a = 11;
    }
}

public class Test {
    public static void main(String args[]) throws IOException {
        Parent p1 = new Child();
        p1.method();
    }
}
我得到的输出是

在父级中
在child中
10

有人能告诉我为什么它引用父类的实例变量
a
,而不是子类的
a

另一个疑问是,我理解隐藏方法,当父类和子类中存在静态方法时,也声明了具有相同签名的静态方法。这是什么意思?隐藏的方法是什么?如果是父母的方法,你能解释一下吗

提前感谢。

实例变量不会在子类中重写。如果在类中定义的变量与在超类中定义的变量同名,则称为变量的阴影
继承和多态性
不适用于实例变量。如果在父类中定义方法()并在子类中重写它。由于运行时多态性打印11

 parent p1 = new child();
  • 调用子构造函数
  • 使用super()调用调用的父级构造函数
  • 打印“在父项中”,并将父项的a初始化为10
  • print在child中,并将child的a初始化为11

        p1.method();// this invokes Child's method() during run-time
    
  • 不能在子类中重写Java实例变量。Java继承不是这样工作的

  • 在您的示例中,没有正在进行的方法隐藏(或重写或重载)

  • 不过,实例变量是隐藏的。在类
    child
    中,
    a
    的声明隐藏了
    parent
    a
    的声明,而
    child
    类中对
    a
    的所有引用都是指
    子级。a
    不是
    父级.a

  • 为了更清楚地说明这一点,请尝试运行以下命令:

    public static void main(String args[]) throws IOException {
        child c1 = new child();
        parent p1 = c1;
    
        System.out.println("p1.a is " + p1.a);
        System.out.println("c1.a is " + c1.a);
        System.out.println("p1 == c1 is " + (p1 == c1));
    }
    
    它应该输出:

        p1.a is 10
        c1.a is 11
        p1 == c1 is true
    
    这表明有一个对象具有两个不同的字段,称为
    a
    。。。如果访问权限允许,您可以获得这两个值



    最后,您应该学习遵循标准Java标识符约定。类名应始终以大写字母开头。

    问题在于您创建了一个子实例并将其存储在父实例的引用中。因此,当您访问对象的属性时,JVM引用父对象的变量值

    如果它是子类的引用变量,则会收到子类的变量值


    以上是Java的一个特性。

    当您创建父实例时。因此在运行时编译器调用父对象, 请尝试下面的代码

    public static void main(String args[]) throws IOException {
        child c1 = new child();
        c1.method();
    }
    
    当你这么做的时候

    父P1=新的子()

    JVM所做的是

                   first  Initialize Parent()
    
                             ||
    
                   second Initialize Child()
    

    因此,首先调用父构造函数,然后调用子构造函数,但输出值将为11,因为p1引用的是子对象。

    因为您没有重写子类中的method(),当

    parent p1 = new child();
    
    则将执行method()的父版本,父类唯一知道的值是其自己的a。因此,它将打印a=10(此时它在堆栈上)


    最后,您只是将变量a从父类映射到子类

    你确定你的代码可以编译吗?你运行了你的代码吗?这不应该编译,父级没有方法
    method()
    很抱歉格式错误。现在更新了代码。回答得好!为了实现相同的想法,即同一对象有两个同名变量:
    Arrays.stream(Child.class.getFields()).map(Field::getName.forEachOrdered(System.out::println)对我来说,这始终不是很直观。