继承方案中引用和对象之间的关系

时间:2017-08-30 02:40:07

标签: java

在Java中,对象引用如何与它引用的实例相关 至?      我遇到了一些非常棘手的事情,并希望对它有深刻的理解。在下面的场景中,子类的shine()会覆盖超类的那个(这是正常的),但是name属性是超类的属性,尽管在子类上调用了NEW(我觉得很奇怪!)有人会帮我吗明白这一点?

class Father {
    public String name = "John Senior";
    public void shine() {
        System.out.println(name + "'s shining");
    }
}

//Subclass
class Son extends Father {
    public String name = "John Junior";
    public void shine() {
        System.out.println(name + "'s shining");
    }
}

//Demo Class
class Test {
    public static void main(String[] args) {
        Father f1 = new Son();
        System.out.println(f1.name);
        f1.shine();
    }
}

//program output

/*John Senior
John Junior's shining */

3 个答案:

答案 0 :(得分:2)

变量在Java中不是多态的;他们不会互相覆盖。方法是多态的。因此上述行为。 如果要打印超级成员,请使用super关键字。

答案 1 :(得分:1)

你观察到的行为起初可能并不直观,但事实上,因为正如@ shaggy-d所提到的,变量不是多态的。让我解释一下,发生了什么,但首先忘记了shine()方法,让我们先了解name

以下是main方法的其他一些示例,其中包含相应的输出和说明:

示例1:

public static void main(String[] args) {
    Object f1 = new Son();
    System.out.println(Father.class.cast(f1).name);
    System.out.println(Son.class.cast(f1).name);
}

输出:

John Senior
John Junior

您实际上隐藏了f1变量的类型,并说Hi Java let's treat at within the scope as对象. So now when you want to get the名称, you actually need to tell Java what it should think of the object, i.e., is it a父亲or a儿子. Depending on your decision, Java picks what名称 - 要使用的属性。

示例2:

public static void main(String[] args) {
    Son f1 = new Son();
    System.out.println(Father.class.cast(f1).name);
    System.out.println(Son.class.cast(f1).name);
    System.out.println(f1.name);
}

输出:

John Senior
John Junior
John Junior

正如预期的那样,当您告诉Java该对象应该在您的范围内被视为Son时,它会解析儿子的name(如果没有明确表示其他情况。

现在回到您的shine()方法。再次提到@ shaggy-d,方法是多态的。因此,在调用对象的方法时,Java确定对象层次结构中“最低”的可用实现并执行该方法。

答案 2 :(得分:1)

enter image description here

我将尝试用图解释它:当我们实例化router.route()时,还会创建一个Son的实例,它会被创建:在引擎的构造函数被调用之前 - 父的构造函数也被调用,因此Father的新实例也具有它所扩展的类中对象的上下文。

现在,由于您将Son声明为F1类型,因此在评估Father时,会在f1.name的上下文中查找它 - 这就是我们的方式得到“高级”。

但是当调用该方法时,多态“启动”并且被调用的方法是属于Father的方法(并且它会覆盖Son的方法)。之所以发生这种情况,是因为我们已将Father分配给new Son()