Спрятанные методы суперкласса - PullRequest
8 голосов
/ 14 сентября 2011

Я прочитал учебник Методы переопределения и сокрытия .И из этого я получил следующее:

Если подкласс определяет метод класса с той же сигнатурой, что и метод класса в суперклассе, метод в подклассе скрывает один в суперклассе.

Таким образом, я сделал следующее:

import javax.swing.JTextArea;

public final class JWrappedLabel extends JTextArea{
    private static final long serialVersionUID = -844167470113830283L;

    public JWrappedLabel(final String text){
        super(text);
        setOpaque(false);
        setEditable(false);
        setLineWrap(true);
        setWrapStyleWord(true);
    }

    @Override
    public void append(final String s){
        throw new UnsupportedOperationException();
    }
}

Что мне не нравится в этом дизайне, так это то, что append по-прежнему видимый метод подкласса.Вместо того, чтобы выбросить UnsupportedOperationException, я мог бы оставить тело пустым.Но оба чувствуют себя ужасно.

При этом существует ли лучший подход к сокрытию методов суперкласса?

Ответы [ 3 ]

11 голосов
/ 14 сентября 2011

Используйте композицию, если это возможно. Это рекомендовано Джошуа Блохом в Effective Java, Second Edition .

Пункт 16: Композиция Favour по наследству

Например:

import javax.swing.JTextArea;

public final class JWrappedLabel {
    private static final long serialVersionUID = -844167470113830283L;

    private final JTextArea textArea;

    public JWrappedLabel(final String text){
        textArea = new JTextArea(text);
        textArea.setOpaque(false);
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
    }

    //add methods which delegate calls to the textArea
}
3 голосов
/ 14 сентября 2011

Нет, о котором я знаю.

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

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

1 голос
/ 14 сентября 2011

Да, используйте делегат вместо расширения .

...