модификаторы доступа к Java и методы переопределения

Почему Java указывает, что спецификатор доступа для переопределяющего метода может предоставить больше, но не менее, доступ, чем переопределенный метод? Например, метод защищенного экземпляра в суперclassе может быть общедоступным, но не закрытым, в подclassе.

Это основополагающий принцип в ООП: дочерний class является полноправным экземпляром родительского classа и поэтому должен содержать по крайней мере тот же интерфейс, что и родительский class. Сделать менее видимыми защищенные / общественные вещи нарушат эту идею; вы можете сделать дочерние classы непригодными для использования в качестве экземпляров родительского classа.

Представьте себе эти два classа:

 public class Animal { public String getName() { return this.name; } } public class Lion extends Animal { private String getName() { return this.name; } } 

Я мог бы написать этот код:

 Animal lion = new Lion(); System.out.println( lion.getName() ); 

И это должно было бы быть справедливым, так как на Animal метод getName () является общедоступным, даже если он был закрыт на Lion . Таким образом, невозможно сделать вещи менее заметными на подclassах, как только у вас есть ссылка на суперclass, с которой вы сможете получить доступ к этому материалу.

Потому что это было бы странно:

 class A { public void blah() {} } class B extends A { private void blah() {} } B b = new B(); A a = b; b.blah(); // Can't do it! a.blah(); // Can do it, even though it's the same object! 

Приведите приведенный ниже пример

  class Person{ public void display(){ //some operation } } class Employee extends Person{ private void display(){ //some operation } } 

Типичное переопределение происходит в следующем случае

 Person p=new Employee(); 

Здесь p – ссылка на объект с типом Person (суперclass), когда мы вызываем p.display () . Поскольку модификатор доступа более ограничительный, ссылка на объект p не может получить доступ к дочернему объекту типа Employee

Поздно к партии, но я хотел бы добавить еще одну проблему, связанную с переопределением: метод переопределения должен допускать исключение (или одинаковый уровень), исключающее исключение, чем переопределенный метод; даже ничего не подбрасываемое вообще.

Принцип замещения Лискова также может объяснить это:

 interface Actionable { void action() throws DislocationException; } public class Actor implements Actionable { @Override public void action() throws DislocationException { //.... } } public class Stuntman implements Actionable { @Override // this will cause compiler error public void action() throws DislocationException, DeathException { //.... } } // legacy code to use Actionable try { Actionable actor = new Actor(); // this cannot be replaced by a Stuntman, // or it may break the try/catch block actor.action(); } catch (DislocationException exc) { // Do something else } 

Выше, переопределенный метод сделал обязательство, что в худшем случае он выкинет DislocationException, не более (врач должен быть на месте съемок). Таким образом, метод переопределения не должен нарушать его, добавляя больше исключений DeathException (или нужна скорая помощь)

Я часто называю переопределяющим правилом «[может быть] больше доступа [уровень], [но] меньше исключений»

Поскольку подclass является специализацией суперclassа, или, другими словами, это расширение суперclassа.

Представьте себе, например, метод toString. Все объекты Java имеют это, потому что объект classа имеет его. Представьте, что вы можете определить class с помощью метода toString private. Затем вы больше не относитесь ко всем объектам одинаково. Например, вы больше не сможете этого безопасно:

for (Object obj : collection) System.out.println(obj);

Ну, с точки зрения конкретного случая, о котором вы говорили, как именно Java справится с этим? Если подclass сделал открытый / защищенный метод приватным, то что должен делать JVM, когда этот метод вызывается в экземпляре подclassа? Почитайте частные и вызывают реализацию суперclassа? Кроме того, вы нарушаете контракт, указанный суперclassом, когда вы вдруг говорите: «Никто не может получить доступ к этому методу, несмотря на то, что контракт первоначально сказал».

  • Переопределение и скрытие Java - Confused
  • Каковы правила для вызова конструктора суперclassа?
  • Может ли интерфейс расширять несколько интерфейсов в Java?
  • Entity Framework DB-First, реализовать наследование
  • Почему метод classа C #, реализованный в classе, должен быть общедоступным?
  • Наследование из списка
  • Могу ли я переопределить свойство в c #? Как?
  • Функция с тем же именем, но другая подпись в производном classе
  • Почему невозможно расширять annotations в Java?
  • Должен ли я избегать многозадачного (конкретного) наследования в Django любыми способами?
  • Почему classы java не наследуют annotations от реализованных интерфейсов?
  • Interesting Posts

    Android SDK: получить изображение предварительного просмотра камеры без его отображения

    Лучший способ изменить строку

    Как определить язык строки?

    Синхронизация конструктора в Java

    Почему SSLSocket Java отправляет приветствие клиента версии 2?

    Как я могу создать элемент управления ActiveX, написанный с помощью событий C # для повышения в JavaScript при нажатии?

    Динамический двумерный массив с указателем на указатель

    Как использовать Tomcat 8.5.x и TomEE 7.x с Eclipse?

    Выравнивание памяти в C-структурах

    Как вызвать метод асинхронизации с геттера или сеттера?

    Доступ к электронным таблицам Google с помощью C # с использованием API данных Google

    Возможна ли прямая трансляция с ПК с Windows на телевизор с поддержкой DLNA?

    Overflow-x: скрытый не предотвращает переполнение содержимого в мобильных браузерах

    Строка не была признана действительным DateTime “format dd / MM / yyyy”

    Самый простой способ обновить eclipse от 3.7 до 4.2 (Juno)

    Давайте будем гением компьютера.