q(x) is true for any x of T and q(y) is true for any y of S => S is a subtype of T
Ответ Нет . Это выражение означает, что общий супертип R для S и T может быть определен, и что тогда LSP (позор тому, как это имя стало массовым) будет сохраняться для T-> R и S-> R.
В теории типизации есть типы, которые включают семантику, и есть реализации типов, которые соответствуют семантике, возможно, путем наследования реализаций.
На практике единственный разумный способ указать семантику типа (часть q(x)
) - это реализация, поэтому у нас остаются менее семантические подписи в виде интерфейсов , и классы , которые наследуют для целей реализации и реализуют интерфейсы, которые им нравятся, без возможности проверить, правильно ли они это делают.
Исследователи пытались определить формальные языки для определения типов, поэтому инструменты могут проверить, соответствует ли реализация определениям типов, но усилия настолько велики, что было бы полезно скомпилировать формальный язык в исполняемый код Это ситуация Catch-22 , которая, я думаю, никогда не будет решена.
Возвращаясь к вашему первоначальному вопросу, на языках, которые допускают то, что сегодня называется «Duck Typing», ответ неразрешим, потому что объект любого типа может быть передан любой функции, и набор будет правильным, если правильные сигнатуры реализовано и результат правильный. Позвольте мне объяснить ...
На языке, подобном Eiffel , вы можете поместить постусловие на List.append()
, которое List.length()
должно увеличиться после операции. Так не работают языки вроде Perl, JavaScript, Python или даже Java. Это отсутствие строгости типов допускает гораздо более сжатый код, чем более строгие определения типов.