Изменить модификатор доступа переопределенного метода в Java? - PullRequest
17 голосов
/ 17 февраля 2012

Есть ли причина, по которой можно изменить модификатор доступа переопределенного метода?Например,

abstract class Foo{
    void start(){...}
}

А затем измените модификатор доступа к пакету на public,

final class Bar extends Foo{
    @Override
    public void start(){...}
}

Я просто задаю этот вопрос из любопытства.

Ответы [ 5 ]

19 голосов
/ 17 февраля 2012

Java не позволяет сделать модификатор доступа более ограничительным , потому что это нарушит правило, согласно которому экземпляр подкласса должен использоваться вместо экземпляра суперкласса. Но когда дело доходит до ограничения доступа менее ... ну, возможно, суперкласс был написан другим человеком, и они не ожидали, что вы захотите использовать их класс.

Программы, которые пишут люди, и ситуации, возникающие при программировании, настолько разнообразны, что разработчикам языков лучше не «догадываться», что программисты могут захотеть сделать со своим языком. Если нет веской причины, по которой программист должен , а не иметь возможность сделать спецификаторы доступа менее ограничительными в подклассе (например), тогда лучше оставить это решение программисту. Они знают специфику своей индивидуальной ситуации, а дизайнер языка - нет. Поэтому я думаю, что это был хороший призыв со стороны разработчиков Java.

6 голосов
/ 17 февраля 2012

Расширение класса означает, что подкласс должен по крайней мере предлагать ту же функциональность другим классам.

Если он расширяет это, то это не проблема.

Расширение может быть либо добавлением новых методов, либо предложением существующих методов большему количеству классов, например, открытием метода доступа к пакету.

6 голосов
/ 17 февраля 2012

Существует только один, вы можете захотеть, чтобы переопределение было видно большему количеству классов, так как по умолчанию нет модификатора, public расширяет его.

2 голосов
/ 09 декабря 2013

Объяснение таково: -

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

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

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


 Person p=new Employee();

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

1 голос
/ 17 февраля 2012

Редактировать: ОК, я изменил свой ответ, чтобы исправить проблему.

Если это невозможно, то в некоторых случаях класс не сможетреализовать интерфейс и расширить класс, потому что они имеют один и тот же метод с разными модификаторами доступа.

public Interface A {
  public void method();
}

public abstract classs B {
  protected void method();
}

public class AB extends B implements A {
  /*
   * This would't be possible if the access modifier coulnd't be changed
   * to less restrictive
  */
  public void method();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...