Должны ли конструкторы соответствовать Принципу замещения Лискова?
Обычно я стараюсь, чтобы мои экземпляры объектов соответствовали Принцип замены Лискова, но я всегда думал, что люди думают LSP должен также применяться к конструкторам?
Я пробовал искать походы для этого, но я не смог найти никаких сильных мнений в любом случае.
Я должен отметить, что большая часть моего кодирования находится в Ruby, но иногда я обнаруживаю, что мои конструкторы подкласса немного отличаются от родительского класса. Они используют один и тот же базовый набор аргументов, а часто и дополнительные аргументы. Иногда это также происходит с другими методами класса.
В задней части моей головы это всегда было похоже на нарушение LSP, но я хотел посмотреть, чувствует ли кто-то еще этот способ тоже.
Ответы
Ответ 1
Нет, когда вы используете конструктор, вы знаете, что имеете дело с подтипом. Это позволяет использовать предварительные условия для родительского конструктора, такие как другие параметры. Вот почему в большинстве языков имя конструктора - это имя создаваемого класса.
Хорошим примером того, как это может быть ColoredSquare
, может быть правильный подтип Square
, но требует дополнительного параметра: color
. Если бы вы не могли делать такие вещи, как этот подтипы были бы гораздо менее полезными.
В некотором смысле конструктор не является частью этого типа: это функция, которая возвращает элемент этого типа. Таким образом, определение нового конструктора для подтипа не нарушает LSV.
Ответ 2
Определенно Нет.
Конструкторы обычно специализируются на подтипы. Попытка применить LSP к конструкторам будет похожа на то, что подтипы не могут добавлять определенные методы или члены. Но ограничение только наоборот.
И я также согласен с Philip, конструкторы на самом деле не являются частью типа (и на некоторых языках вы можете легко использовать другие фабрики вместо конструкторов). Используя терминологию smalltalk, вы бы сказали, что конструкторы - это методы метаклассов.
Здесь нет нарушения LSP, оно применимо только к методам экземпляра, а не к методам класса (конструкторам или любым другим методам класса).
Ответ 3
Это своего рода упрямый вопрос, но способ, которым я склонен писать мой, таков, что дополнительные параметры не имеют реального влияния на изменение функциональности. Под этим я подразумеваю, что, когда мой конструктор требует дополнительного параметра в подклассе, он должен поддерживать стандартную функциональность (но делать разные базовые вещи), таким образом, я могу сказать, что я создаю ClassA = новый ClassB (с некоторыми аргументами); то функциональность такая же, независимо от того, выполняю ли я это или ClassA = new ClassA(); и я обычно использую какой-то метод Factory, чтобы создать их, чтобы он не зависал в том, как они работают. Опять же, это то, как я делаю то, и отнюдь не является абсолютно правильным способом делать что-то.