为什么即使我只调用一次super.speak,该代码在执行时仍会打印两次“ Woof”?

问题描述

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

这是超级混乱的,因为我不确定为什么即使我只调用一次超级类的语音方法也要运行两次。最终结果是“ Woof \ n Woof \ n arf arf”。

解决方法

即使我只调用过一次,我也不确定为什么超类的语音方法会运行两次。

您叫了两次。

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

编辑:

因为我们叫b.speak,d.speak-

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

它调用super.speak()。 super.speak()仅意味着在父类(恰好是Dog类)的peak()方法中执行代码。这样就会显示“ 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"
} 
,

基本上,在super.speak()类中调用Beagle时,您要拨打两次电话。如果要消除重复的呼叫,则可能要删除super.speak()呼叫。调用super时,您正在调用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方法,这样可以理解您是在超类中覆盖该方法。

旁注我也将主要方法与Super类分开了……如果您开始使用Java编程,我将研究 SOLID 原理,第一个是“ S ”以表示单一职责。基本上,这意味着每个类和方法都应该只承担一个责任。