История изменений
Исправление korvin_, (текущая версия) :
«Функции, которые используют базовый тип, должны иметь возможность использовать подтипы базового типа, не зная об этом.» (с) определение LSK.
Нет такого определения. Есть такое: «in a computer program, if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e. an object of type T may be substituted with any object of a subtype S) without altering any of the desirable properties of T (correctness, task performed, etc.)»
Попытка заменить Interface на InterfaceChild приводит к ошибке компиляции.
Потому что LSP не про замену типов, а про замену значений подтипа в месте, где ожидается супертип этого подтипа.
И правильно приводит, т.к. Implementation не является подтипом InterfaceChild. Ты не подставляешь значение типа S (являющегося подтипом T) в метод, ожидающий значение типа T, а меняешь T на T', подтипом которого S не является. LSP тут вообще не при чём.
Даже по твоему определению: есть функция (var T = val T) :: T -> ()
ожидающая T для val, вместо объекта типа T подставляем объект типа S = Implementation <: T
— всё работает, т.к. S является субтипом T. Меняем сигнатуру на (var T' = val T') :: T' -> ()
, пробуем снова подставить S, ничего не работает, т.к. S не является подтипом T'. Всё логично.
Исправление korvin_, :
«Функции, которые используют базовый тип, должны иметь возможность использовать подтипы базового типа, не зная об этом.» (с) определение LSK.
Нет такого определения. Есть такое: «in a computer program, if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e. an object of type T may be substituted with any object of a subtype S) without altering any of the desirable properties of T (correctness, task performed, etc.)»
Попытка заменить Interface на InterfaceChild приводит к ошибке компиляции.
Потому что LSP не про замену типов, а про замену значений подтипа в месте, где ожидается супертип этого подтипа.
И правильно приводит, т.к. Implementation не является подтипом InterfaceChild. Ты не подставляешь значение типа S (являющегося подтипом T) в метод, ожидающий значение типа T, а меняешь T на T', подтипом которого S не является. LSP тут вообще не при чём.
Даже по твоему определению: есть функция (var T = val T) :: T -> ()
ожидающая T для val, вместо T подставляем S = Implementation <: T
— всё работает, т.к. S является субтипом T. Меняем сигнатуру на (var T' = val T') :: T' -> ()
, пробуем снова подставить S, ничего не работает, т.к. S не является подтипом T'. Всё логично.
Исходная версия korvin_, :
«Функции, которые используют базовый тип, должны иметь возможность использовать подтипы базового типа, не зная об этом.» (с) определение LSK.
Нет такого определения. Есть такое: «in a computer program, if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e. an object of type T may be substituted with any object of a subtype S) without altering any of the desirable properties of T (correctness, task performed, etc.)»
Попытка заменить Interface на InterfaceChild приводит к ошибке компиляции.
Потому что LSP не про замену типов, а про замену значений подтипа в месте, где ожидается супертип этого подтипа.
И правильно приводит, т.к. Implementation не является подтипом InterfaceChild. Ты не подставляешь значение типа S (являющегося подтипом T) в метод, ожидающий значение типа T, а меняешь T на T', подтипом которого S не является. LSP тут вообще не при чём.