在通过继承进行方法调用时遇到了理解困难。

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

Having trouble with understanding in method call via inheritance

问题

以下是翻译好的内容:

我有一个父类 Animal,它被类 Dog 继承了。

public class Animal {
    private String color;
    private Boolean hasTail;
    private Integer legs;

    public Animal(String color, Boolean hasTail, Integer legs) {
        this.color = color;
        this.hasTail = hasTail;
        this.legs = legs;
    }

    protected void speak() {
        System.out.println("动物在说话");
        sleep();
    }

    public void sleep() {
        System.out.println("动物在睡觉");
    }
}

public class Dog extends Animal {

    public Dog(String name) {
        super("黑色", true, 4);
        this.name = name;
    }

    private String name;

    public void bark() {
        System.out.println("汪汪汪");
        super.speak();
    }

    public void sleep() {
        System.out.println("狗在睡觉");
    }
}

当我执行以下代码:

Dog d = new Dog("汤米");
d.bark();

输出结果是:

汪汪汪
动物在说话
狗在睡觉

但我本来期望输出结果是:

汪汪汪
动物在说话
动物在睡觉

所以有人能详细解释一下为什么会出现这种情况吗?因为 Animal 类应该调用自己类中的 sleep 方法,而不是 Dog 类中的 sleep 方法,这是我的理解。另外,如何知道某个类是否被继承了呢?

编辑1:如果我将 Animal 类中的 sleep 方法从 public 改为 private,那么我会得到第二个输出。对象仍然是 Dog 类型,所以为什么现在会产生第二个输出?

英文:

I have a parent class Animal which is inherited by class Dog


    public class Animal {
        private String color;
        private Boolean hasTail;
        private Integer legs;
    
        public Animal(String color, Boolean hasTail , Integer legs){
            this.color = color;
            this.hasTail = hasTail;
            this.legs = legs;
        }
    
        protected void speak(){
            System.out.println("the animal is speaking");
            sleep();
        }
    
        public void  sleep(){
            System.out.println("The animal is sleeping");
        }
    }

    public class Dog extends Animal {
    
        public Dog(String name) {
            super("Black", true, 12);
            this.name = name;
        }
    
        private String name;
    
        public void bark() {
            System.out.println("bow bow bow");
            super.speak();
        }
    
        public void  sleep(){
            System.out.println("The Dog is sleeping");
        }
    }

and when i do

Dog d = new Dog("tommy");
        d.bark();

the output is

bow bow bow
the animal is speaking
The Dog is sleeping

but i was expecting that the output would be

bow bow bow
the animal is speaking
The animal is sleeping

so anyone can please explain in detail that how this is happening? as Animal class should call the sleep method of it's own class and not of the Dog class that's what i was under the impression of and also how does this know if any class has inherited it?

EDIT1:- if i change the method sleep in Animal class from public to private then I am getting the second output .The object is still type of Dog so why it is now giving the second output?

答案1

得分: 2

在**speak方法中调用sleep方法时,由于你的对象属于Dog类,显然它将调用Dog类**中的sleep方法。

如果你想调用Animal类的sleep方法,只需在Dog的sleep方法中简单地添加**super.sleep**。

public void sleep(){
    super.sleep();
}
英文:

While calling sleep method from speak, as your object is belongs to Dog class obviously it will call sleep method from Dog class.

If you want to call sleep method of Animal class then simply put super.sleep in Dog's sleep method.

 public void  sleep(){
        super.sleep();
    }

答案2

得分: 0

你覆盖了睡眠而不是说话。

因此,当你创建一个Dog的实例时,它使用Animal的说话方法(因为它在Dog中未重新定义),但同时也使用Dog的睡眠方法,因为它被重写了。

如果你想达到你的目标,你应该这样做:

public class Dog extends Animal {

    public Dog(String name) {
        super("Black", true, 12);
        this.name = name;
    }

    private String name;

    public void bark() {
        System.out.println("bow bow bow");
        super.speak();
    }

    public void sleep() {
        super.sleep();
        System.out.println("The Dog is sleeping");
    }
}

然后你将会得到:

bow bow bow
the animal is speaking
The animal is sleeping
The Dog is sleeping

你明白吗?

英文:

You overrided sleep and not speak.

So, when you create an instance of Dog, it uses the Animal speak method (as it is not redifined in Dog) but uses also the Dog sleep method as it is overwritten.

If you want to reach your goal, you should do :

public class Dog extends Animal {

    public Dog(String name) {
        super("Black", true, 12);
        this.name = name;
    }

    private String name;

    public void bark() {
        System.out.println("bow bow bow");
        super.speak();
    }

    public void  sleep(){
        super.sleep();
        System.out.println("The Dog is sleeping");
    }
}

And then you will have

bow bow bow
the animal is speaking
The animal is sleeping
The Dog is sleeping

Do you understand ?

答案3

得分: 0

调用 super 只有在你想要调用父类方法,并且同时存在一个同名的子类方法(即父类方法的重写)时才有意义。
Dog 没有 speak() 方法,所以 super.speak() 中的 super 是多余的。直接调用 speak(),会得到相同的结果。

回答第二部分:
将方法更改为 private 表示它只对其自身类可见。父类的 sleep() 现在无法被子类看到,这意味着子类的 sleep() 现在是一个独立的方法,而不是一个重写。
如果你试图从父类方法中调用仅子类拥有的方法(即不是重写的方法),代码将无法编译通过。通过从 speak() 中调用 bark() 进行测试。
在这个例子中,对方法 sleep() 的调用会绑定到合适的方法,即 Animal 类中的私有方法。

英文:

Calling with super only makes sense when you want to call a parent method when there's also a child method of the same name (i.e. override of the parent method).
Dog has no speak() so the super in super.speak() is redundant. Call speak() by itself and get the same result.

To answer the 2nd part:<br>
Changing a method to private means it's only visible to its own class. The parent sleep() can't now be seen by the child, meaning the child sleep() is now a separate method, not an override.
If you try to call a child-only method (i.e. not an override) from a parent method, it won't compile. Test by calling bark() from speak().<br>
Your call to method sleep() in this example binds to the method that makes sense, the private method in Animal.

huangapple
  • 本文由 发表于 2020年8月23日 23:18:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/63548662.html
匿名

发表评论

匿名网友

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

确定