Java继承覆盖实例变量

时间:2013-02-18 09:56:55

标签: java oop

我正在学习java。我对遗产有疑问。当子类扩展父类时,父类有一个方法引用父类中声明的实例变量。但是,子类dint会覆盖此方法,并声明了与父类同名的实例变量。在这种情况下,将引用来自child的实例变量或将引用parent。以下是代码段

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

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

6 个答案:

答案 0 :(得分:20)

  1. 无法在子类中重写Java实例变量。 Java继承不起作用。

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

  3. 虽然隐藏了实例变量。在课程child中,a的声明隐藏了aparent的声明,以及a类中对child的所有引用到child.a而不是parent.a

  4. 为了更清楚地说明这一点,请尝试运行:

    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标识符约定。类名应始终以大写字母开头。

答案 1 :(得分:2)

Instance variables are not overriden in sub-class。如果在类中使用与超类中相同的名称定义变量,则称为变量的阴影 inheritance and polymorphism不适用于实例变量。如果在父类中定义method()并在Child类中重写它。由于运行时多态打印 11

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

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

答案 2 :(得分:1)

当你这样做时

父P1 =新Child();

JVM做的是什么

               first  Initialize Parent()

                         ||

               second Initialize Child()

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

答案 3 :(得分:1)

因为你没有在子类中重写method(),所以语句

parent p1 = new child();
执行

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

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

答案 4 :(得分:0)

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

如果它是一个子类的引用变量,你就会收到子类的变量值。

以上是Java的一个特性。

答案 5 :(得分:0)

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

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