Эта статья поднимает множество проблем. Пожалуйста, помогите улучшить его или обсудите эти проблемы на странице обсуждения . ( Узнайте, как и когда удалить эти сообщения-шаблоны ) ( Узнайте, как и когда удалить этот шаблон сообщения )
|
В представлении знаний , объектно-ориентированном программировании и дизайне (см. Объектно -ориентированную программную архитектуру ) is-a ( is_a или is a ) является отношением подчинения [1] между абстракциями (например, типами , классами ), при этом один класс A является подкласс другого класса B (и так B является суперкласс из A ). Другими словами, тип A является подтипом типа B, когда Aспецификация подразумевает спецификацию B. То есть любой объект (или класс), который удовлетворяет спецификации A, также удовлетворяет спецификации B, потому что спецификация B слабее. [2]
Отношение is-a следует противопоставить отношениям has-a ( has_a или has a ) между типами (классами); путаница в отношениях has-a и is-a - распространенная ошибка при разработке модели (например, компьютерной программы ) реальных отношений между объектом и его подчиненным. Отношение is-a можно также противопоставить отношениям instance-of между объектами (экземплярами) и типами (классами): см. Различие типа и токена .
Подводя итог отношениям, можно выделить:
- гипероним - гипоним (супертип / суперкласс – подтип / подкласс) отношения между типами (классами), определяющие таксономическую иерархию, где
- для отношения подчинения : гипоним (подтип, подкласс) имеет отношение типа ( является ) со своим гиперонимом (супертип, суперкласс);
- холоним - мероним (целое / сущность / контейнер – часть / составляющая / член) отношения между типами (классами), определяющие притяжательную иерархию, где
- для отношения агрегации (т.е. без собственности):
- holonym (вся) имеет имеет-а отношения с его meronym (часть),
- для отношения композиции (т.е. с правом собственности):
- мероним (составляющая) имеет частичное отношение со своим холонимом (сущностью),
- для отношения включения [3] :
- мероним (член) имеет отношение члена со своим холонимом ( контейнером );
- для отношения агрегации (т.е. без собственности):
- понятие – объект (тип – токен) отношения между типами (классами) и объектами (экземплярами), где
- токен (объект) имеет отношение экземпляра со своим типом (классом).
Примеры подтипов [ править ]
Подтипирование позволяет заменить данный тип другим типом или абстракцией. Подтипирование сказано учредить есть- связь между подтипом и некоторыми существующими абстракциями, явно или неявно, в зависимости от языковой поддержки. Отношения могут быть явно выражены через наследование на языках, которые поддерживают наследование как механизм выделения подтипов.
C ++ [ править ]
Следующий код C ++ устанавливает явное отношение наследования между классами B и A , где B является как подклассом, так и подтипом A , и может использоваться как A везде, где указан B (через ссылку, указатель или сам объект ).
class A { public : void DoSomethingALike () const {} };класс B : общественность A { public : void DoSomethingBLike () const {} };void UseAnA ( A const & some_A ) { some_A . DoSomethingALike (); }void SomeFunc () { B b ; UseAnA ( b ); // b можно заменить на A. }
[4]
Python [ править ]
Следующий код Python устанавливает явное отношение наследования между классами B и A , где B является одновременно и подклассом подтипа А , и может быть использован в качестве А везде , где Б требуется.
класс A : def do_something_a_like ( self ): passкласс B ( A ): def do_something_b_like ( self ): passdef use_an_a ( some_a ): some_a . do_something_a_like ()def some_func (): b = B () use_an_a ( b ) # b можно заменить на A.
В следующем примере type (a) - это «обычный» тип, а type (type (a)) - это метатип. Хотя распределенные типы имеют один и тот же метатип ( PyType_Type , который также является его собственным метатипом), это не является обязательным требованием. Тип классических классов, известный как types.ClassType , также можно рассматривать как отдельный метатип. [5]
>>> a = 0 >>> type ( a ) <type 'int'> >>> type ( type ( a )) <type 'type'> >>> type ( type ( type ( a ))) <type 'тип'> >>> тип ( тип ( тип ( тип ( a )))) <тип 'тип'>
Java [ править ]
В Java, это-а соотношение между параметрами типа одного класса или интерфейса и параметров типа другого определяются расширяется и реализует положения.
Используя классы Collections, ArrayList <E> реализует List <E>, а List <E> расширяет Collection <E>. Итак, ArrayList <String> является подтипом List <String>, который является подтипом Collection <String>. Связь подтипов сохраняется между типами автоматически. При определении интерфейса PayloadList, который связывает необязательное значение универсального типа P с каждым элементом, его объявление может выглядеть так:
интерфейс PayloadList < E , P > расширяет список < E > { void setPayload ( int index , P val ); ... }
Следующие параметризации PayloadList являются подтипами List <String>:
PayloadList < String , String > PayloadList < String , Integer > PayloadList < String , Exception >
Принцип подстановки Лискова [ править ]
Принцип подстановки Лискова объясняет свойство: «Если для каждого объекта o1 типа S существует объект o2 типа T, такой, что для всех программ P, определенных в терминах T, поведение P не изменяется, когда o1 заменяется на o2, то S является подтипом T, " . [6] В следующем примере показано нарушение LSP.
недействительный DrawShape ( Const Форма & ы ) { если ( TypeId ( ы ) == TypeId ( площадь )) DrawSquare ( static_cast < площадь &> ( ы )); остальное , если ( TypeId ( ы ) == TypeId ( круг )) DrawCircle ( static_cast < круг &> ( ы )); }
Очевидно, функция DrawShape плохо отформатирована. Он должен знать обо всех производных классах класса Shape. Кроме того, его следует менять всякий раз, когда создается новый подкласс Shape. В объектно-ориентированном дизайне многие [ кто? ] рассматривать структуру этого как анафему.
Вот более тонкий пример нарушения LSP:
класс Rectangle { общедоступные : void SetWidth ( двойной ш ) { itsWidth = ш ; } void SetHeight ( двойной h ) { itsHeight = h ; } double GetHeight () const { return itsHeight ; } double GetWidth () const { return itsWidth ; } private : удвоить itsWidth; удвоить itsHeight ; };
Это хорошо работает, но когда дело доходит до класса Square, который наследует класс Rectangle, он нарушает LSP, хотя между Rectangle и Square сохраняется связь is-a . Потому что квадрат прямоугольный. В следующем примере для устранения проблемы переопределяются две функции, Setwidth и SetHeight. Но исправление кода означает, что конструкция ошибочна.
общественный класс Square : Rectangle { public : virtual void SetWidth ( двойной ш ); виртуальная пустота SetHeight ( двойной h ); }; void Square :: SetWidth ( двойной ш ) { Прямоугольник :: SetWidth ( ш ); Прямоугольник :: SetHeight ( ш ); } void Square :: SetHeight (двойной h ) { Прямоугольник :: SetHeight ( h ); Прямоугольник :: SetWidth ( h ); }
В следующем примере функция g работает только с классом Rectangle, но не с Square, поэтому принцип открыт-закрытость был нарушен.
void g ( Прямоугольник & r ) { r . SetWidth ( 5 ); r . SetHeight ( 4 ); assert ( r . GetWidth () * r . GetHeight ()) == 20 ); }
[7]
См. Также [ править ]
- Наследование (объектно-ориентированное программирование)
- Принцип подстановки Лискова (в объектно-ориентированном программировании )
- Потребление
- Это
- Гипернимия (и супертип )
- Гипонимия (и подтип )
- Имеет
- Холонимия
- Меронимия
Заметки [ править ]
- ^ См. Принцип подстановки Лискова .
- ^ «Подтипы и подклассы» (PDF) . MIT OCW . Проверено 2 октября 2012 года .
- ^ См. Также « Сдерживание» (компьютерное программирование) .
- ^ Митчелл, Джон (2002). «10« Понятий в объектно-ориентированных языках » ». Понятия на языке программирования . Кембридж, Великобритания: Издательство Кембриджского университета. п. 287. ISBN. 0-521-78098-5.
- ^ Гвидо ван Россум. «Подтипирование встроенных типов» . Проверено 2 октября 2012 года .
- ^ Лисков, Барбара (май 1988). Абстракция данных и иерархия (PDF) . Уведомления SIGPLAN.
- ^ "Принцип подстановки Лискова" (PDF) . Роберт К. Мартин, 1996. Архивировано из оригинального (PDF) 5 сентября 2015 года . Проверено 2 октября 2012 года .
Ссылки [ править ]
- Рональд Дж. Брахман ; Что такое IS-A, а что нет. Анализ таксономических связей в семантических сетях . IEEE Computer, 16 (10); Октябрь 1983 г.
- Жан-Люк Эно, Жан-Марк Хик, Винсент Энгльбер, Жан Хенрар, Дидье Ролан: понимание реализации отношений IS-A . ER 1996: 42-57