0

我正在玩继承以尝试完全理解它:

我创建了一个带有私有方法的父类,并在子类中重写了它并将其公开。我还为每个类以不同的方式覆盖了 toString 方法。看起来像这样:

public class testparent {
    public String toString(){
        return ("One and two boobaloo");
    }
    private void hitMe(){
        System.out.println("BAM");
    }
}

public class testbaby extends testparent{
    public String toString() {
        return "Bananas";
    }
    public void hitMe(){
        System.out.println("BAMBAM");
    }
    public static void main(String[] args){
        testbaby testy = new testbaby();
        testparent test2 = testy;
        System.out.println(test2);
        //test2.hitMe(); //????? not allowed
        System.out.println(testy);
        testy.hitMe();
    }
}

现在,为什么打印两个对象都会产生“香蕉”,但我不能同时使用这两个类的 hitMe() 方法?

4

2 回答 2

5

这是因为方法的动态绑定和语言本身的静态类型

发生的情况是 Java 是静态类型的并且具有动态绑定,因此:

  • 该方法hitMe只能在testbaby声明的变量上调用,因为它是私有的,testparent并且由于静态类型,Java 必须确保可以在运行时肯定调用该方法
  • 该方法toString可以在两个对象上调用(因为它甚至是从 继承的Object),并且哪个将在运行时有效调用它是根据运行时实例而不是根据变量声明选择的(因为动态绑定)

根据动态绑定方法,方法的正确和运行时实现是在运行时根据对象的真实实例而不是在声明的实例上选择的。

这意味着,即使您声明test2为 a testparent,它仍然是一个testbaby对象(因为您正在为它分配一个testbaby实例)。在运行时,正确的实现将是孩子之一。

这是完全合法的,因为 atestbaby a testparent

于 2012-04-19T20:23:10.117 回答
3

基本上,因为当您声明test2为 type 的变量时testparent,您是在故意丢弃test2“实际上”为 a的知识testbaby

这是继承的一部分——任何使用test2的代码都只允许假设它是 的一个testparent或一个子类testparent,并且该代码必须适用于所有 testparent对象,即使是那些不是对象的testbaby对象。

仅供参考,就任何外部testParent而言,该testParent.hitMe()方法甚至都不存在(除了一些基于反射的邪恶事物,在这个阶段你不应该担心)。连方法testbaby都不知道testParent.hitMe()

于 2012-04-19T20:21:08.567 回答