История изменений
Исправление den73, (текущая версия) :
В общем я понял, что подкласс, вообще говоря - не подтип. Т.е. в стандарте CL ошибка, а в С++ и Яве отношение «являться» некорректно терминологически, хотя логической ошибки в самом языке нет. И вообще, подтип - это понятие «логическое». С физической точки зрения нет отношения подтип, а есть просто «тип», т.е. способ размещения в памяти и идентификации объекта.
Т.е. в нормальном объектном языке программирования должны различаться понятие «подтип», которое служит основой для отношения «являться», и понятие «наследник», которое служит для полиморфизма наследников класса и которое в реальности чаще встречается.
Я это раньше выражал в том, что требовал наличия понятия «только конкретно этот класс, не считая потомков», но в реальности тут появляется больше понятий:
- «этот тип (логически)» - здесь подходит и любой подтип в смысле Лисков
- «этот тип (физически), в точности» - здесь мы ждём ровно нужный нам тег типа
- «этот класс или его наследники (физически)» - для работы с виртуальными функциями и полями, которые случайно оказались на том же месте в С++ из-за наследования.
- «этот класс или его наследники (логически)» - для языков, у которых более сложно устроены классы и поэтому мы не можем рассчитывать на ту же оптимизацию за счёт совместимости расположения полей, что в С++. В C++ в этот случай можно условно поместить множественное наследование.
Если иерархия удовлетворяет принципу Лисков, то подкласс становится подтипом. В идеальном ООП языке это понимает компилятор.
Исходная версия den73, :
В общем я понял, что подкласс, вообще говоря - не подтип. Т.е. в стандарте CL ошибка. И вообще, подтип - это понятие «логическое». С физической точки зрения нет отношения подтип, а есть просто «тип», т.е. способ размещения в памяти и идентификации объекта.
Т.е. в нормальном объектном языке программирования должны различаться понятие «подтип», которое служит основой для отношения «являться», и понятие «наследник», которое служит для полиморфизма наследников класса и которое в реальности чаще встречается.
Я это раньше выражал в том, что требовал наличия понятия «только конкретно этот класс, не считая потомков», но в реальности тут появляется больше понятий:
- «этот тип (логически)» - здесь подходит и любой подтип в смысле Лисков
- «этот тип (физически), в точности» - здесь мы ждём ровно нужный нам тег типа
- «этот класс или его наследники (физически)» - для работы с виртуальными функциями и полями, которые случайно оказались на том же месте в С++ из-за наследования.
- «этот класс или его наследники (логически)» - для языков, у которых более сложно устроены классы и поэтому мы не можем рассчитывать на ту же оптимизацию за счёт совместимости расположения полей, что в С++. В C++ в этот случай можно условно поместить множественное наследование.
Если иерархия удовлетворяет принципу Лисков, то подкласс становится подтипом. В идеальном ООП языке это понимает компилятор.