С точки зрения языка программирования, что означает подтип? Я слышал, что «Наследование - это не подтип». Тогда каковы различия между наследованием и подтипом?
С точки зрения языка программирования, что означает подтип? Я слышал, что «Наследование - это не подтип». Тогда каковы различия между наследованием и подтипом?
Ответы:
[Я не задумывался о проблемах объектно-ориентированных систем типов, но я скажу то, что знаю, чтобы начать обсуждение.]
Мы говорим, что является подтипом если все значения типа могут использоваться в каждом контексте, где ожидаются значения типа. Или, иначе говоря, -typed значение может «маскироваться» в качестве -typed значения.B A B A B
Если такое маскирование не создает проблем с проверкой типов, т. Е. Подключение значений типа где требуются значения типа , продолжает проверку типа, мы называем это «структурным подтипом» . Если это не вызывает проблем с поведением, то есть такое подключение не изменяет ожидаемое поведение, тогда мы называем это «поведенческим подтипом» . («Ожидаемое поведение» должно быть оформлено отдельно, и возможны многие понятия поведения.)B
Структурный подтип не обеспечивает поведенческий подтип, потому что структура типа может совпадать по случайным причинам. Однако определить ожидаемое поведение непросто. Таким образом, многие языки программирования используют промежуточную точку, где пользователь должен объявить, какой тип является подтипом какого. Это называется «номинальным подтипом» . Смотрите вопрос о неявном и явном подтипированиидля обсуждения этого вопроса. Идея состоит в том, что программист должен обеспечить поведенческие подтипы для всех объявленных подтипов, используя свою изобретательность. Язык не может предложить никакой помощи. Однако все объявленные подтипы должны быть как минимум структурными подтипами. В противном случае программа не сможет проверить тип. Язык может помочь обеспечить это. (Некоторые языки программирования не имеют достаточно хороших систем типов, чтобы гарантировать это во время компиляции. Если это так, то сбой типа будет обнаружен во время выполнения, или, возможно, могут быть получены неправильные результаты. Такие дыры в типах явно нежелательны.)
Когда кто-то определяет подклассы в объектно-ориентированных программах, он обычно добавляет публично видимые поля (или методы). В большинстве языков программирования такие подклассы рассматриваются как номинальные подтипы. Вопрос в том, являются ли они также структурными подтипами. Если это не так, т.е. язык программирования позволяет объявлять номинальные подтипы, которые не являются структурными, то в языке программирования могут быть дыры типов.
В простых случаях добавление полей работает нормально. Тип суперкласса ожидает меньше полей, чем тип подкласса. Таким образом, если вы подключите экземпляр подкласса, где ожидается экземпляр класса sueprclass, программа просто проигнорирует предоставленные дополнительные поля, и ничего не пойдет не так.
Однако, если у суперкласса или подкласса есть методы, которые принимают аргументы того же типа, что и он сам, или возвращают результаты того же типа, что и он сам, тогда возникают проблемы. Тогда тип интерфейса подкласса не является структурным подтипом подкласса суперкласса. Широко используемые типобезопасные языки программирования, такие как Java, не допускают таких подклассов. Таким образом, они ограничивают язык для обеспечения безопасности типов. Говорят, что язык программирования Eiffel пожертвовал безопасностью типов, чтобы добиться гибкости . Если кто-то разрабатывает сильную систему типов, которая сохраняет гибкость, он должен отказаться от принципа, согласно которому подклассы порождают подтипы. Отсюда и название статьи «Наследование не подтип», Авторы предлагают другое понятие подтипа высшего порядка, которое работает вместо этого. У Ким Брюса также есть тесно связанное предложение под названием «сопоставление», которое достигает того же эффекта. Смотрите эту презентацию . Также полезным является документ с изложением позиции Эндрю Блэка.
Сообщество семантики, вероятно, виновато в том, что в значительной степени игнорирует проблему. Мы традиционно рассматривали это как практическую проблему системного проектирования, которая не представляет большого теоретического интереса. Если это не так и в этой области действительно есть какая-то семантика, я надеюсь, что другие люди упомянут о них.