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

huangapple go评论60阅读模式
英文:

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

这很令人困惑,因为我不确定为什么即使我只调用了一次,超类的speak方法会被运行两次。最终结果是:"Woof \n Woof \n arf arf"。

英文:
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");
    }
}

This is super confusing, because I am not sure why the speak method of the super class is being run twice even if I called it just once. The final result is "Woof \n Woof \n arf arf".

答案1

得分: 3

我不确定为什么超类的speak方法会被运行两次,即使我只调用了一次。

你调用了两次。

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

编辑:

因为我们在调用b.speak,d.speak -

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

它调用了 super.speak()。super.speak() 简单地意味着执行父类的 speak() 方法中的代码,而这恰好是 Dog 类。所以 "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();

以查看如上所述的输出。

英文:

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

You call it twice.

  1. You call it directly when you invoke d.speak();
  2. Then you call it indirectly when you invoke b.speak() since b.speak() first invokes super.speak().

Edit:

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

b.speak() does NOT display "woof" directly. There is no println(...) statement to display "woof".

It invokes super.speak(). The super.speak() simply means execute the code in the speak() method of the parent class which happens to be the Dog class. So "woof" is displayed.

Then it displays "arf arf".

So:

  1. d.speak() causes "woof" to be displayed.
  2. b.speak() causes "woof" and "arf arf"to be displayed.

Change your code to be:

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

to see the output as described above.

答案2

得分: 1

看见注释中的标记

public static void main(String[] args)
{
    Dog d = new Dog();
    d.speak();  // 调用 Dog.speak() -> 输出 "woof!"
    Dog b = new Beagle();
    b.speak(); // 调用 Beagle.speak() -> 
               // 通过调用 super.speak() 输出 "woof!" 
               // 然后输出 "arf arf"
}
英文:

See annotations in comments.

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"
} 

答案3

得分: 0

基本上,当在Beagle类中调用super.speak()时,你实际上进行了两次调用。如果你想要消除重复的调用,你可能想要删除super.speak()的调用。当你调用super时,你正在调用超类方法。

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方法,这样可以清楚地表明你正在重写超类的方法。

附注
我还将主方法与超类分开... 如果你刚开始学习Java编程,我建议你了解一下SOLID原则,其中的第一个原则是“S”,即Single Responsibility(单一职责原则)。基本上,这意味着每个类和方法应该只有一个职责。

英文:

Basically you are making the call twice when you invoque super.speak() in Beagle class. If you want to eliminate the duplicate call, you might want to delete the super.speak() call. When you call super, you are invoking the super class method.

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

Also, you might want to annotate the Beagle.speak method with @Override, so that is understandable that you are overriding the method from the super class.

Side Note:
I have also separated the main method from the Super class... If you are getting started with Java programming, I would take a look at SOLID principles, first one been "S" for Single Responsibility. Basically this means that every class and method should have only one responsibility.

huangapple
  • 本文由 发表于 2020年8月16日 08:32:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/63432034.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定