簡體   English   中英

通過繼承理解方法調用時遇到問題

[英]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("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");
        }
    }

當我這樣做時

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

輸出是

bow bow bow
the animal is speaking
The Dog is sleeping

但我期待輸出會是

bow bow bow
the animal is speaking
The animal is sleeping

所以任何人都可以詳細解釋這是怎么發生的? 因為 Animal 類應該調用它自己的類的 sleep 方法而不是 Dog 類的方法,這就是我的印象,而且這如何知道是否有任何類繼承了它?

EDIT1:- 如果我將 Animal 類中的方法 sleep 從 public 更改為 private 那么我將獲得第二個輸出。對象仍然是 Dog 類型,那么為什么它現在給出第二個輸出?

speak調用 sleep 方法時,由於您的對象屬於 Dog 類,顯然它會從Dog class調用 sleep 方法。

如果你想調用 Animal 類的 sleep 方法,那么只需將super.sleep放在 Dog 的 sleep 方法中。

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

你覆蓋了睡眠而不說話。

因此,當您創建 Dog 實例時,它使用 Animal speak 方法(因為它沒有在 Dog 中重新定義),但也使用 Dog sleep 方法,因為它被覆蓋了。

如果你想達到你的目標,你應該這樣做:

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

你明白嗎 ?

僅當您想調用父方法時,還有同名的子方法(即父方法的覆蓋)時,使用 super 調用才有意義。 Dog 沒有speak()所以super.speak()的 super 是多余的。 單獨調用speak()並獲得相同的結果。

回答第二部分:
將方法更改為私有意味着它只對它自己的類可見。 孩子現在不能看到父sleep() ,這意味着孩子sleep()現在是一個單獨的方法,而不是覆蓋。
如果您嘗試從父方法調用僅子方法(即不是覆蓋),它將無法編譯。 通過從speak()調用bark()測試。
在此示例中,您對方法sleep()調用綁定到有意義的方法,即 Animal 中的私有方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM