Как правило, отдавайте предпочтение композиции, а не наследованию. Наследование имеет тенденцию нарушать инкапсуляцию . например Если класс зависит от метода суперкласса, и суперкласс меняет реализацию этого метода в некотором выпуске, подкласс может сломаться.
Иногда, когда вы разрабатываете фреймворк, у вас будет для разработки классов, которые будут наследоваться. Если вы хотите использовать наследование, вам придется тщательно документировать и разрабатывать его. например Не вызывать какие-либо методы экземпляра (которые могут быть переопределены вашими подклассами) в конструкторе. Также, если это подлинное отношение «есть», наследование полезно, но оно более надежно, если используется в пакете.
См. Эффективная Java (пункты 14 и 15). Это дает хороший аргумент, почему вы должны отдавать предпочтение композиции, а не наследованию. В нем говорится о наследовании и инкапсуляции в целом (с примерами Java). Так что это хороший ресурс, даже если вы не используете Java.
Итак, чтобы ответить на ваши 3 вопроса:
Можно ли просто не наследовать или наследовать? Должен ли я быть обеспокоен вообще?
Ответ: Задайте себе вопрос, действительно ли это отношения "is-a"? Возможно ли украшение? Перейти на украшение
// A collection decorator that is-a collection with
public class MyCustomCollection implements java.util.Collection {
private Collection delegate;
// decorate methods with custom code
}
Какие у вас есть стратегии для определения объектов, которые могут получить выгоду от наследования?
Ответ: Обычно, когда вы пишете фреймворк, вам может потребоваться предоставить определенные интерфейсы и «базовые» классы, специально предназначенные для наследования.
Допустимо ли всегда наследовать на основе поведения (интерфейсов), а не фактического типа?
Ответ: В основном да, но вам будет лучше, если суперкласс предназначен для наследования и / или под вашим контролем. Или же пойти на композицию.