Как я могу запретить доступ к методу суперкласса? - PullRequest
1 голос
/ 17 апреля 2011

Мне было интересно, как я могу запретить доступ к методу суперкласса класса?

Пример: у меня есть класс Door и класс Emptyness, который по сути является просто открытой дверью для моего приложенияТеперь я хочу унаследовать большинство методов дверей, но не хочу, чтобы пользователь мог вызывать метод «закрыть дверь» на пустоту, как я могу это сделать?

Ответы [ 5 ]

3 голосов
/ 17 апреля 2011

Мы явно не можем уменьшить видимость при переопределении метода. Если метод закрытия двери в Door равен public, переопределенный метод в Emptyness не может быть закрытым ...

Обычный подход - переопределить метод закрытой двери в Emptyness и просто ничего не делать или выдавать UnsupportedOperationException (как это делают разработчики Iterator, если они не позволяют удалить элемент).

Пример:

 public class Door {
   public void closeDoor() {
     // closing door actions
   }
 }

 public class Emptyness extends Door {
   @Override void closeDoor() {
     // do nothing or
     throw new UnsupportedOperationException("Can't close door on Emptyness");
   }
 }
2 голосов
/ 17 апреля 2011

Похоже, что Emptyness не проходит тест «должен быть подклассом» в отношении Door. Проверка состоит в том, что верно следующее предложение: Emptyness - это Door. Поскольку Door может быть закрыто, Emptyness не соответствует этому требованию.

Рекомендовать использовать агрегацию, а не наследование. Пусть Emptyness реализует свой собственный интерфейс (или другой соответствующий интерфейс, но не Door), а содержит Door экземпляр, который он использует для выполнения соответствующих операций.

Делать что-то вроде переопределения операции close, чтобы ничего не делать или генерировать исключение, совершенно неуместно , если Door#close не определен как необязательный (через тег throws для соответствующего исключения) , (И остерегайтесь «необязательных» операций в иерархиях классов, они обычно указывают на проблему проектирования. Не всегда, но обычно.) Пример, который Андреас приводит для Iterator#remove, например: Iterator#remove помечен как бросать UnsupportedOperationException. Если Door#close помечен таким образом, и если вы чувствуете себя комфортно при таком способе ведения дел, прекрасно, вы здесь. Но если этого не произойдет, то Emptyness не сможет выполнить контракт Door, что обычно означает, что вам нужно пойти другим путем.

0 голосов
/ 18 апреля 2011

Почему бы не использовать Designer Pattern. Так как метод closeDoor не является общим для всех подклассов Door, он вообще не должен присутствовать в классе Door; вместо этого создайте интерфейс с именем Closable с помощью метода close, реализуйте этот интерфейс в некоторых классах, таких как ClosableTrue и ClosableFalse. Теперь создайте ссылочную переменную в классе Door типа Closable и инициализируйте ее в конструкторе класса с помощью объекта ClosableTrue или ClosableFalse в зависимости от типа аргумента, передаваемого конструктору. Теперь всякий раз, когда метод close вызывается для любого объекта Door или подкласса Door, будет вызываться метод, класс которого использовался для инициализации конструктора Door. Вы можете реализовать метод close класса ClosableFalse без какой-либо значимой функциональности.

0 голосов
/ 17 апреля 2011

Вариантов много. Выберите то, что соответствует вашим потребностям

  1. Сделать метод private
  2. Сделайте метод final, чтобы он не мог быть переопределен, а также добавьте логику, проверяющую, вызывается ли метод из instanceof Пустота, а затем выдает исключение.

     public class Emptiness extends Door{
    
    
            public static void main(String[] args) throws Exception {
                Door x = new Emptiness();
                x.somemethod();
            }
    
        }
    

    Дверной класс

    public class Door {         
            final public void somemethod() throws Exception{
                if(this instanceof Emptiness){
                    throw new Exception();
                }
            }
        }
    
0 голосов
/ 17 апреля 2011

Сделать это приватным в классе Door .Потому что если у вас есть открытый или защищенный суперкласс, то у вас не может быть более строгий модификатор доступа в иерархии вниз .Таким образом, вы не можете сделать приватным в пустом классе, скорее вы должны сделать это в классе Door.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...