Java 使用更严格的访问修饰符重写方法

Java 使用更严格的访问修饰符重写方法,java,Java,我想知道: 为什么重写方法不能有比被重写方法更严格的访问修饰符 例如: 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,

我想知道: 为什么重写方法不能有比被重写方法更严格的访问修饰符

例如:

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");
    }
}
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");
    }
}
在Horse类中,为什么我不能这样编写代码:

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

还记得每个孩子都是父母的原则吗

假设您已经创建了一个实例

Animal animal = new Horse();
如果有人做了
animal.eat()
现在该怎么办


拥有
eat()
方法且具有足够权限的动物,同时您已将
Horse
中的
eat()
访问权限限制为
private
,这意味着您只能在Horse内部访问该方法。糟糕。

它违反了多态性原则(子类实例应该可以用来代替超类实例)

这是OOP的主要概念之一

扩展类时,不能限制可见性,因为如果创建该子类的新实例,则会出现概念错误

例如:

Animal animal = new Horse();
在这种情况下,
animal
have method
eat
public但
horse
private不起作用。创建扩展
Animal
的类实例,我希望能够访问
eat
方法

否则,可以在子类中扩展方法可见性,例如:

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");
    }
}
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");
    }
}
  • 当你说“马延伸动物”时,意思是你正在建立 马是动物的关系

    现在假设这是可能的:

    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               
      } 
    
    现在,如果您尝试用马实例替换此动物姿态:

      private Horse horseInstance = new Horse();                     
      horseInstance .eat(); // Error! Horse doesn't expose this method to outside world!!
    
    这将导致编译时错误。如果是动物呢 实例不能被马实例替换,那么马不是 动物你违反了是一种关系

  • 这还有一个方面。当你说方法重写时,它 是运行时多态性。意味着,在运行时,编译器将检查 子类已重写此方法,然后应用子行为, 否则家长的行为。在上述情况下,它什么时候会试着跑马 行为,这将失败,因为马是私人的

    这种问题在另一种情况下不会发生——在哪里 使用限制较少的访问修饰符进行子重写


  • 希望这能消除您的疑虑。

    您应该用
    @Override
    注释被重写的函数,因为这样您就不能调用
    Animal-Animal=new-Horse();eat()
    因为
    eat()
    方法是私有的。但是
    Animal
    class宣布它是公共的。这毫无意义。这应该是一个评论。@QBrute抱歉,我是新手。@QBrute你为什么这么认为?这显然是为了回答问题,而不是寻求更多信息或提供旁注。