【问题标题】:Java inheritance overriding instance variable [duplicate]Java继承覆盖实例变量[重复]
【发布时间】:2013-02-18 09:56:55
【问题描述】:

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

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();
    }
}

我得到的输出是

在父级
在孩子
10

谁能让我理解为什么它引用父类的实例变量a 而不是子类的a

另一个疑问是,我理解隐藏方法,当父类和子类中有静态方法时,也声明了具有相同签名的静态方法。这里隐藏意味着什么?什么方法被隐藏了?如果它是父方法,你能解释一下吗?
提前致谢。

【问题讨论】:

  • 你确定你的代码可以编译吗?你运行你的代码了吗?
  • 这不应该编译,父级没有方法method()
  • 抱歉,格式错误。现在更新代码。

标签: java oop


【解决方案1】:
  1. Java 实例变量不能在子类中被覆盖。 Java 继承不能那样工作。

  2. 在您的示例中,没有方法隐藏(或覆盖或重载)正在进行。

  3. 虽然隐藏了实例变量。在child 类中,a 的声明隐藏了parenta 的声明,并且child 类中对a 的所有引用都引用child.a 而不是parent.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 标识符约定。类名应始终以大写字母开头。

【讨论】:

  • 好答案!执行相同的想法,即同一个对象有两个具有相同名称的变量:Arrays.stream(Child.class.getFields()) .map(Field::getName) .forEachOrdered(System.out::println); 这对我来说始终不是很直观。
【解决方案2】:

Instance variables are not overriden in sub-class。如果你在你的类中定义一个与你的超类同名的变量,它被称为shadowing of variables inheritance and polymorphism 不适用于实例变量。如果您在父类中定义 method() 并在子类中覆盖它。由于运行时多态性打印 11

,下面将调用 Child 的 method()
 parent p1 = new child();
  1. 调用子构造函数
  2. 使用 super() 调用调用父级的构造函数
  3. 打印“在父级中”并将父级的 a 初始化为 10
  4. print's in child 并将 Childs a 初始化为 11

        p1.method();// this invokes Child's method() during run-time
    

【讨论】:

    【解决方案3】:

    由于您没有在子类中覆盖method(),因此当声明时,

    parent p1 = new child();
    

    被执行,method() 的父版本将被执行,并且父类唯一知道的值是它自己的 a。因此它将打印 a=10 (因为它当时在堆栈上)。

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

    【讨论】:

      【解决方案4】:

      当你这样做时

      父 P1=new Child();

      JVM 所做的是

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

      所以,首先调用 Parent 构造函数,然后调用 child's ,但输出值将是 11 ,因为 p1 是指 child 的对象。

      【讨论】:

        【解决方案5】:

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

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

        以上是Java的一个特性。

        【讨论】:

          【解决方案6】:

          在创建父实例时。所以在运行时编译器调用父对象, 试试下面的代码。

          public static void main(String args[]) throws IOException {
              child c1 = new child();
              c1.method();
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-11-05
            • 1970-01-01
            • 2020-07-07
            • 2011-11-11
            相关资源
            最近更新 更多