Из Википедии, бесплатной энциклопедии
Перейти к навигации Перейти к поиску

В представлении знаний , объектно-ориентированном программировании и дизайне (см. Объектно -ориентированную программную архитектуру ) 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]

См. Также [ править ]

  • Наследование (объектно-ориентированное программирование)
  • Принцип подстановки Лискова (в объектно-ориентированном программировании )
  • Потребление
  • Это
    • Гипернимия (и супертип )
    • Гипонимия (и подтип )
  • Имеет
    • Холонимия
    • Меронимия

Заметки [ править ]

  1. ^ См. Принцип подстановки Лискова .
  2. ^ «Подтипы и подклассы» (PDF) . MIT OCW . Проверено 2 октября 2012 года .
  3. ^ См. Также « Сдерживание» (компьютерное программирование) .
  4. ^ Митчелл, Джон (2002). «10« Понятий в объектно-ориентированных языках » ». Понятия на языке программирования . Кембридж, Великобритания: Издательство Кембриджского университета. п. 287. ISBN. 0-521-78098-5.
  5. ^ Гвидо ван Россум. «Подтипирование встроенных типов» . Проверено 2 октября 2012 года .
  6. ^ Лисков, Барбара (май 1988). Абстракция данных и иерархия (PDF) . Уведомления SIGPLAN.
  7. ^ "Принцип подстановки Лискова" (PDF) . Роберт К. Мартин, 1996. Архивировано из оригинального (PDF) 5 сентября 2015 года . Проверено 2 октября 2012 года .

Ссылки [ править ]

  • Рональд Дж. Брахман ; Что такое IS-A, а что нет. Анализ таксономических связей в семантических сетях . IEEE Computer, 16 (10); Октябрь 1983 г.
  • Жан-Люк Эно, Жан-Марк Хик, Винсент Энгльбер, Жан Хенрар, Дидье Ролан: понимание реализации отношений IS-A . ER 1996: 42-57