2017-07-14 61 views
2

的方法,我想知道:爲什麼 重寫的方法不能比方法更嚴格的訪問修飾符被重寫?覆蓋有更嚴格的訪問修飾符

例如:

class Animal{ 
    public void eat(){ 
     System.out.println("Generic Animal Eating Generically"); 
    } 
} 

class Horse extends Animal{ 
    public void eat(){ 
     System.out.println("Horse eating hay, oats, and horse treats"); 
    } 
} 

在馬類,我爲什麼不能寫這樣的代碼:

private void eat(){ 
    System.out.println("Horse eating hay, oats, and horse treats"); 
} 

protected void eat(){ 
    System.out.println("Horse eating hay, oats, and horse treats"); 
} 
+0

你應該標註一個重寫的功能與''@Override因爲 – baao

+0

那麼你不能叫'獸獸=新馬(); animal.eat()'因爲'eat()'方法是私有的。但「動物」類宣稱它是​​公開的。這沒有意義。 – Gondy

回答

6

記住一個原則每一個兒童是家長

假設你已經創建了一個實例

Animal animal = new Horse(); 

當有人做animal.eat()什麼現在應該發生的呢?有

動物的eat()方法有足夠的權限,並在同一時間,你已經在Horse限於privateeat()訪問這意味着你只能訪問內馬的方法。遊民。

2

它違反了原則多態性(子類的實例應該是可用來代替超類實例)

+1

這應該是一條評論。 – QBrute

+0

@QBrute對不起,我是新手。 – Valentun

+0

@QBrute你爲什麼這麼認爲?它顯然是想回答這個問題,而不是尋求額外的信息或提供一個附註。 –

0

這是當你繼承你不能限制類OOP的Polymorphism

的主要概念之一visibiliy,因爲如果您創建該子類的新實例,則存在概念錯誤。

例子:

Animal animal = new Horse(); 

在這種情況下animal有方法eat公開,但horse私有的,不是作品。創建延伸Animal的類的實例,我希望能夠訪問eat方法。

否則,你可以在子類擴展方法可見,例如:

class Animal{ 
    protected void eat(){ 
     System.out.println("Generic Animal Eating Generically"); 
    } 
} 

class Horse extends Animal{ 
    public void eat(){ 
     System.out.println("Horse eating hay, oats, and horse treats"); 
    } 
} 
1
  1. 當你說馬延長動物,這意味着你正在建立 的關係:馬是動物

    現在假設這是可能的:

    class Animal{ 
        public void eat(){ 
         System.out.println("Generic Animal Eating Generically"); 
        } 
    } 
    
    class Horse extends Animal{ 
        private void eat(){ 
         System.out.println("Horse eating hay, oats, and horse treats"); 
        } 
    } 
    

    假設有第三個類,您正在使用此層次結構。現在

    class B{ 
        Animal animalInstance = new Animal() ; 
        animalInstance .eat(); 
        //other code that use this instance    
        } 
    

    ,如果你嘗試更換此animalInstance與馬例如:

    private Horse horseInstance = new Horse();      
        horseInstance .eat(); // Error! Horse doesn't expose this method to outside world!! 
    

    那麼這將導致到一個編譯時錯誤。如果動物 實例不能由馬實例來代替,那麼馬不是 動物!您違反了IS A的關係。

  2. 有這一個更多的方面。當你說方法覆蓋時,它是 是運行時多態性。意思是,在運行時,編譯器會檢查,如果 子類已覆蓋此方法,則應用子行爲, 其他父行爲。在上面的情況下,當它試圖運行馬時,這將會失敗,因爲馬正在將它變爲私有。

    這種問題不會在另一種情況下發生 - 在 孩子覆蓋有較少限制的訪問修飾符。

希望這會消除你的疑惑。