2016-12-13 2 views
1

В моем проекте Java у меня есть метод addType1AndType2(), в котором есть окна, где вы разворачиваете списки и выбираете объекты из списка. Это было очень сложным и трудоемким для создания, поскольку вещи должны быть прокручены, а xpaths продолжают меняться. В этом списке есть два списка, которые являются фактическими именами, но из-за собственной информации о компании я просто назову их Tyep1 и Type2.Как запретить подкласс использовать метод?

Теперь у меня есть класс UpdateType1, который использует всю сложную методологию в AddType1AndType2, но не имеет ничего общего с Type2. Я мог бы скопировать AddType1AndType2 и вырезать все, что мне не нужно, но это будет репликация, и изменения должны быть дублированы в обоих классах. Это побеждает цель наследования и повторного использования.

Я могу сделать class UpdateType1 extends AddType1AndType2{}, который я сделал. Но есть еще такие методы, как selectType2Value(), которые наследуются, но недоступны в подклассе.

Если я делаю @Override и объявляю класс приватным в подклассе, я получаю сообщение об ошибке, которое я не могу уменьшить видимость в подклассе.

Любая идея, что я могу сделать? Прямо сейчас я просто помещаю throw new AssertError("Do not use"), но это похоже на хромых. Есть ли лучшее, что можно было бы сделать, это даже даст ошибку времени компиляции, а не утверждение во время выполнения, или это лучший способ?

+2

Объявить метод final https://docs.oracle.com/javase/tutorial/java/IandI/final.html – Kon

+0

Я также не вижу исключения в качестве лучшего решения. Тем не менее, рассмотрите возможность использования 'java.lang.UnsupportedOperationException'. Это так же слабо, но более интегрировано с существующей средой. – bruno

+1

Боковое примечание при именовании: имена методов go camelCase в java. – GhostCat

ответ

1

Создание интерфейсах

public interface IAddType1 {... /* methods signtatures to add Type1 */} 
public interface IAddType2 {... /* methods signtatures to add Type2 */} 
public interface IUpdateType1 {... /* methods signtatures to update Type1 */} 

тогда ваш текущий код на AddType1AndType2 будет только базовый вспомогательный класс:

public abstract class BaseOperationsType1AndType2{ 
    //code originally at AddType1AndType2: methods that add Type1 and Type2 
} 

тогда ваш новый AddType1AndType2 класс будет:

public class AddType1AndType2 
    extends BaseOperationsType1AndType2, 
    implements IAddType1 , IAddType2 { 
     //nothing special. 
} 

и ваш новый UpdateType1 можно определить как

public class UpdateType1 
     extends BaseOperationsType1AndType2 
     implements IUpdateType1 { 
     // 
} 

Voila.

3

Дело в том, что ваша модель неверна.

Inheritance is more, чем просто положить «A extends B» в исходный код. А продолжается B означает: А «является» Б.

Всякий раз, когда вы используете объект B, вы должны быть в состоянии Погружает Объект вместо (называется Liskov substitution principle).

Короче говоря: если B имеет методы, которые не должны иметь ... то вы не должны иметь расширяет B.

Таким образом, реальный ответ: вы должны сделать шаг назад и тщательно решить, какие методы вы действительно хочу доля. Вы помещаете их в свой базовый класс. Что-то еще нужно. Возможно, вы, вероятно, определите дополнительные интерфейсы и другие базовые классы, например

class EnhancedBase extends Base implements AdditionalStuff { 

Редактировать: с учетом вашего комментария; лучший способ будет:

  1. Создание интерфейсов, которые обозначают различные группы методов, которые должны идти вместе
  2. Вместо того простирающиеся что базовый класс, использовать состав: создать новый класс А, который использует некоторый объект B, чтобы реализовать один или несколько новых интерфейсов.

И помните, что это как хороший пример, почему LSP действительно имеет смысл ;-)

+0

Очень верно. Тем не менее, класс существует некоторое время и интегрирован в систему ;-( – Tony

+0

Добавлены некоторые обновления, надеюсь, они будут полезны – GhostCat

0

Вы можете использовать «окончательный» ключевое слово, чтобы запретить расширение метода в подклассе.

Метод с модификатором 'final' не может быть переопределен в подклассе.

Смежные вопросы