Подтвердить что ты не робот

Отключение унаследованного метода от производного класса

Есть ли способ в производном классе Java "отключить" метод и/или поле, которое иначе унаследовано от базового класса?

Например, скажем, у вас есть базовый класс Shape, который имеет метод rotate(). У вас также есть различные типы, полученные из класса Shape: Square, Circle, UpwardArrow и т.д.

Shape имеет метод rotate(). Но я не хочу, чтобы rotate() был доступен пользователям Circle, потому что это бессмысленно или пользователи UpwardArrow, потому что я не хочу, чтобы UpwardArrow мог поворачиваться.

4b9b3361

Ответ 1

Я не думаю, что это возможно. Однако вы можете дополнительно уточнить класс Shape с помощью удаления метода rotate() из его спецификации и вместо этого определить другой подкласс Shape, называемый RotatableShape и получить от Shape и всех остальных классов с возможностью вращения от RotatableShape.

>

например:

public class Shape{
 //all the generic methods except rotate()
}

public class RotatableShape extends Shape{

 public void rotate(){
    //Some Code here...
 }
}

public class Circle extends Shape{
 //Your implementation specific to Circle
}

public class Rectangle extends RotatableShape{
 //Your implementation specific to Rectangle
}

Ответ 2

Вы можете переопределить конкретный метод "rotate()" в классе, который вы хотите отключить эту операцию, например

public void rotate() {
    throw new UnsupportedOperationException();
}

Ответ 3

У вас плохая иерархия классов, если вам нужно отключить методы в дочерних классах. Любой подкласс должен уметь беспрепятственно использовать методы своих суперклассов. Это называется "Принцип замещения Лискова" (https://en.wikipedia.org/wiki/Liskov_substitution_principle). Вы можете прочитать больше об этом в этой теме: https://softwareengineering.stackexchange.com/questions/219543/should-a-class-know-about-its-subclasses.

Делай то, что предлагает Чанду. Не помещайте rotate() в Shape. Вместо этого создайте подкласс Shape с именем RotatableShape и поместите в него rotate(). Тогда Circle может наследовать от Shape, а Rectangle может наследовать от RotatableShape.

Ответ 4

Нет.

  • вы можете вывести метод только в классе Circle (или интерфейсе, который реализуется только этим классом)
  • вы можете предоставить пустые реализации или те, которые бросают UnsupportedOperationException в классы, которые его не поддерживают.

Ответ 5

Объявление той же функции в классе "child" перезапишет функцию по умолчанию, объявленную в базовом классе. Поэтому в вашем дочернем классе создайте функцию с именем rotate(), которая ничего не делает, что перезапишет поведение по умолчанию

Ответ 6

Можете ли вы использовать метод empy (ничего не делает) для круга? Для стрелки я бы пересмотрел иерархию объектов

Ответ 7

Один из способов борьбы с этим - определить второй метод, называемый (скажем) boolean isRotatable(), и использовать его для определения того, доступны ли элементы управления поворотом для пользователя.

Другой вариант - ввести интерфейс Rotatable и использовать shape instanceof Rotatable для определения. (Тем не менее, я думаю, что подход isRotatable() более гибкий.)

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

public void rotate() {
    throw new UnsupportedOperationException("rotate");
}

Язык Java не предоставляет способ "удалить" или "отключить" метод в подклассе. Это нарушит принцип взаимозаменяемости и нарушит полиморфизм. Подкласс не может удалить видимые элементы из API родительских классов.

Ответ 8

Я не думаю, что вы можете отключить метод так, как вы предлагаете.

В вашем примере, скажем, у вас есть метод, который принимает форму

public void handleShape(Shape s){
  s.rotate();
}

Затем вы передаете круг этому методу

handleShape(new Circle());

Что должно случиться? По сути, вы просите о фундаментальном изменении системы Java-типа.

Если круг - это форма, и его нельзя поворачивать, это, вероятно, означает, что Shape был разработан плохо и не должен иметь метод поворота. Вы можете добавить поворот в другой класс в иерархию типа RotatableShape или, возможно, с помощью интерфейса Rotatable.

Ответ 9

Итак, здесь есть две возможности. Во-первых, у вас есть объект, который может вращаться, но не показывает никаких изменений в этом процессе. Другой заключается в том, что у вас есть объект, который определяется его направлением. Каждый из них должен обрабатываться отдельно и по-своему.

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

В моем случае я определяю точку в трехмерном пространстве, наследуя операции от класса, определяющего кватернион. 3-мерная точка использует только 3 мнимые координаты кватерниона, и если кватернион имеет отличное от нуля значение для реальной компоненты, он разрушит жизненно важные операции алгоритма рендеринга, унаследованные от кватерниона, через трехмерную координату.

Извините меня за то, что я слишком философский, однако этот вопрос поднимает действительный момент в CS о том, как это следует обрабатывать. Как отмечает Стивен, возможность скрыть, отключить или удалить унаследованную функцию в дочернем классе "... нарушит принцип взаимозаменяемости и нарушит полиморфизм".

Мое дело попадает под восходящую стрелку, за исключением того, что я указываю на воображение. Я пытаюсь усечь производный класс, что означает, что любой класс "внука" (возможно, наследующий спиновые операторы) уже не обязательно будет кватернионами. Было бы более элегантно избегать использования исключений, обрезая базовый класс при методе типа для усеченного производного класса. Альтернативой было бы определение трехмерной координаты как отдельного класса с переменной-членом кватерниона; Недостатком является то, что реализация имеет слишком много клея.

Затем я могу поместить новые операции спина в производный класс для трехмерных координат для трех плоскостей (ij, jk, ik), а затем объекты с 3d-вершинами могут вращаться через цикл и одинаковый вызов функции функции для каждой вершины. Вы могли бы самостоятельно отслеживать симметрию, прежде чем вы начнете вращать точки, определяющие поверхность сферы, поэтому вам нужно использовать функцию заглушки и, возможно, реализовать свой собственный "постоянный" флаг.

Ответ 10

Мне нужно то же самое для кастомного алертадиалога. Мне нужно было передать аргумент, который стал доступен только в момент показа, поэтому я реализовал свой метод show (аргумент), но show() тоже работал из-за суперкласса. Был риск того, что я мог вызвать myDlg.show() случайно, без аргументов, и это могло привести к сбою. Чтобы убедиться, что метод суперкласса никогда не вызывается вне моего класса CustomAlertDialog, я добавил к нему метод private static void show(){}. Это.

Итак, чтобы отключить суперметод, сделайте его закрытым и статическим в подклассе. В вашем случае это будет:

 private void rotate(){}