即使我只调用了一次 super.speak() ,为什么这段代码在执行时会打印两次 "Woof"?

Why does this code print "Woof" twice when executed even though I only called super.speak() once?

public class Dog
{
    public void speak()
    {
        System.out.println("woof!");
    }

    public static void main(String[] args)
    {
        Dog d = new Dog();
        d.speak();
        Dog b = new Beagle();
        b.speak();
    }
}

class Beagle extends Dog
{
    public void speak()
    {
        super.speak();
        System.out.println("arf arf");
    }
}

这太令人困惑了,因为我不确定为什么 super class 的 speak 方法被 运行 两次,即使我只调用了一次。最后的结果是“Woof \n Woof \n arf arf”。

I am not sure why the speak method of the super class is being run twice even if I called it just once.*.

你调用了两次。

  1. 调用d.speak();
  2. 时直接调用
  3. 然后在调用 b.speak() 时间接调用它,因为 b.speak() 首先调用 super.speak()。

编辑:

because we are calling b.speak, d.speak -

b.speak() 不直接显示“woof”。没有 println(...) 语句来显示“woof”。

它调用 super.speak()。 super.speak() 只是意味着执行父 class 的 speak() 方法中的代码,恰好是狗 class。所以显示“woof”。

然后显示“arf arf”。

所以:

  1. d.speak() 导致显示“woof”。
  2. b.speak() 导致显示“woof”和“arf arf”。

将您的代码更改为:

System.out.println("Dog is about to speak:");
d.speak();
Dog b = new Beagle();
System.out.println("Beagle is about to speak:");
b.speak();

查看如上所述的输出。

查看评论中的注释。

public static void main(String[] args)
{
    Dog d = new Dog();
    d.speak();  // calls Dog.speak() -> prints "woof!"
    Dog b = new Beagle();
    b.speak(); // calls Beagle.speak() -> 
               // prints "woof!" via call to super.speak() 
               // and then "arf arf"
} 

基本上,当您在 Beagle class 中调用 super.speak() 时,您正在调用两次。如果要消除重复调用,可能需要删除 super.speak() 调用。当您调用 super 时,您正在调用 super class 方法。

public class Main {

    public static void main(String[] args) {
        Dog d = new Dog();
        d.speak();
        Dog b = new Beagle();
        b.speak();

    }
}

class Dog
{
    public void speak()
    {
        System.out.println("woof!");
    }

}

class Beagle extends Dog
{
    @Override
    public void speak()
    {
//        super.speak();
        System.out.println("arf arf");
    }
}

此外,您可能想用 @Override 注释 Beagle.speak 方法,这样可以理解您正在覆盖超级 class.

中的方法

旁注我还把 main 方法从 Super class 中分离出来了...如果你刚开始 Java 编程,我会看一下 SOLID 原则,第一个是“S”,用于 单一职责。基本上这意味着每个 class 和方法应该只有一个责任。