2017-07-14 7 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 animal = new Horse(); 'eat()'メソッドはprivateなので、animal.eat() 'を呼び出すことができます。しかし、「動物」クラスはそれを公に宣言した。それは理にかなっていません。 – Gondy

答えて

6

原則にすべての子供を覚えておいてください親はですか?

は、誰かが今どうするかanimal.eat()を行う際には、インスタンスに

Animal animal = new Horse(); 

を作成していると仮定しますか?

動物は、十分な権限を持つeat()方法を持つと同時に、あなたは唯一の馬の内側にそのメソッドにアクセスすることができることを意味しprivateHorseeat()のアクセスが制限されています。バマー。

2

それはあなたが制限することはできませんクラスを拡張する場合これは、OOPの主要な概念の1 Polymorphism

ある多型の原則(サブクラスのインスタンスは、スーパークラスのインスタンスの代わりに使用可能でなければなりません)

+1

これはコメントでなければなりません。 – QBrute

+0

@QBrute申し訳ありませんが、私は初心者です。 – Valentun

+0

@QBrouteなぜそう思う?質問に答えて、追加情報を探したり、サイドノートを提供したりしないことは、明らかです。 –

0

に違反なぜなら、その子クラスの新しいインスタンスを作成すると、概念的なエラーが発生するからです。

例:この場合animal

Animal animal = new Horse(); 

メソッドpublic 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"); 
        } 
    } 
    

    この階層を使用している3番目のクラスがあるとします。

    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!! 
    

    その後、これは、コンパイル時にエラーになります。動物 のインスタンスをHorseインスタンスに置き換えることができない場合は、Horse Is Not 動物!あなたはIS Aの関係に違反しています。

  2. もう1つの側面があります。メソッドのオーバーライドを行うと、 はランタイムの多型です。実行時に、コンパイラは、 子クラスがこのメソッドをオーバーライドしている場合は、子の動作を適用し、 の親の動作を確認します。上記のケースでは、ホース の動作を実行しようとすると、Horseはそれをプライベートにしているため、失敗します。

    この種の問題は、他のケースでは発生しません。 制限の少ないアクセス修飾子で子が上書きされます。

希望すると疑いがなくなります。