есть-а
![]() | В этой статье есть несколько проблем. Пожалуйста, помогите улучшить его или обсудите эти проблемы на странице обсуждения . ( Узнайте, как и когда удалять эти шаблонные сообщения )
|
В компонентах представления знаний и онтологии , в том числе для объектно-ориентированного программирования и проектирования , is-a (также пишется как is_a или is a ) является субсумптивным. [ а ] отношения между абстракциями (например, типами , классами ), где один класс A является подклассом другого класса B (и, следовательно, является суперклассом A ) B . Другими словами, тип A является подтипом A типа B, когда спецификация подразумевает спецификацию B. То есть любой объект (или класс), удовлетворяющий спецификации A, также удовлетворяет спецификации B, поскольку спецификация B более слабая. [ 1 ]
Например, кошка «является» животным, но не наоборот. Все кошки — животные, но не все животные — кошки. Поведение, подходящее для всех животных, определяется в классе животных, тогда как поведение, подходящее только для кошек, определяется в классе кошек. Определив класс кошек как «расширение» класса животных, все кошки «наследуют» поведение, определенное для животных, без необходимости явно кодировать это поведение для кошек.
Связанные понятия
[ редактировать ]Отношения is-a следует противопоставлять отношениям has-a ( has_a или has a ) между типами (классами); Путаница отношений has-a и is-a является распространенной ошибкой при разработке модели (например, компьютерной программы ) реальных отношений между объектом и его подчиненным. Отношения is-a можно также противопоставить отношению экземпляра-of между объектами (экземплярами) и типами (классами): см. Различие типа и токена .
Подводя итоги отношений, можно выделить:
- гипероним – гипоним (супертип/суперкласс–подтип/подкласс) отношения между типами (классами), определяющие таксономическую иерархию, где
- для отношения включения : гипоним (подтип, подкласс) имеет отношение типа ( is-a ) со своим гиперонимом (супертипом, суперклассом);
- холоним – мероним (целое/сущность/контейнер-часть/составляющая/член) отношения между типами (классами), определяющие притяжательную иерархию, где
- для отношения агрегации (т.е. без владения):
- холоним (целое) имеет отношение к своему мерониму (части),
- для отношения композиции (т.е. с правом собственности):
- мероним (составляющая) имеет отношение части со своим холонимом (субъектом),
- для сдерживания [ 2 ] связь:
- мероним (член) имеет отношение член-из со своим холонимом ( контейнер );
- для отношения агрегации (т.е. без владения):
- отношения понятие-объект (тип-токен) между типами (классами) и объектами (экземплярами), где
- токен (объект) имеет отношение экземпляра со своим типом (классом).
Примеры подтипирования
[ редактировать ]Подтипирование позволяет заменить данный тип другим типом или абстракцией. Говорят, что подтипирование устанавливает связь между подтипом и некоторой существующей абстракцией, явно или неявно, в зависимости от языковой поддержки. Отношения могут быть выражены явно через наследование в языках, которые поддерживают наследование как механизм подтипирования.
С++
[ редактировать ]Следующий код C++ устанавливает явные отношения наследования между классами B и A , где B является одновременно подклассом и подтипом A и может использоваться как A везде, где указан B (через ссылку, указатель или сам объект). ).
class A
{ public:
void DoSomethingALike() const {}
};
class B : public A
{ public:
void DoSomethingBLike() const {}
};
void UseAnA(A const& some_A)
{
some_A.DoSomethingALike();
}
void SomeFunc()
{
B b;
UseAnA(b); // b can be substituted for an A.
}
Питон
[ редактировать ]Следующий код Python устанавливает явные отношения наследования между классами B и A , где B является одновременно подклассом и подтипом A и может использоваться как A везде, где B. требуется
class A:
def do_something_a_like(self):
pass
class B(A):
def do_something_b_like(self):
pass
def use_an_a(some_a):
some_a.do_something_a_like()
def some_func():
b = B()
use_an_a(b) # b can be substituted for an A.
В следующем примере type(a) — это «обычный» тип, а type(type(a)) — метатип. Хотя при распространении все типы имеют один и тот же метатип ( PyType_Type , который также является собственным метатипом), это не является обязательным требованием. Тип классических классов, известный какtypes.ClassType , также можно считать отдельным метатипом. [ 4 ]
>>> a = 0
>>> type(a)
<type 'int'>
>>> type(type(a))
<type 'type'>
>>> type(type(type(a)))
<type 'type'>
>>> type(type(type(type(a))))
<type 'type'>
Ява
[ редактировать ]В Java is- отношение между параметрами типа одного класса или интерфейса и параметрами типа другого определяется предложениями расширения и реализации .
Используя Collections
занятия, ArrayList<E>
реализует List<E>
, и List<E>
простирается Collection<E>
. Так ArrayList<String>
является подтипом List<String>
, который является подтипом Collection<String>
. Отношения подтипов между типами сохраняются автоматически. При определении интерфейса PayloadList
, который связывает необязательное значение универсального типа P с каждым элементом, его объявление может выглядеть так:
interface PayloadList<E, P> extends List<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», . [ 5 ] Следующий пример показывает нарушение LSP.
Вот, пожалуй, пример нарушения LSP:
class Rectangle
{
public:
void SetWidth(double w) { itsWidth = w; }
void SetHeight(double h) { itsHeight = h; }
double GetHeight() const { return itsHeight; }
double GetWidth() const { return itsWidth; }
double GetArea() const { return GetHeight() * GetWidth(); }
private:
double itsWidth;
double itsHeight;
};
С точки зрения программирования класс Square может быть реализован путем наследования класса Rectangle.
public class Square : Rectangle
{
public:
virtual void SetWidth(double w);
virtual void SetHeight(double h);
};
void Square::SetWidth(double w)
{
Rectangle::SetWidth(w);
Rectangle::SetHeight(w);
}
void Square::SetHeight(double h)
{
Rectangle::SetHeight(h);
Rectangle::SetWidth(h);
}
Однако это нарушает LSP, хотя is-a. между Rectangle и Square сохраняется отношение
Рассмотрим следующий пример, где функция g не работает, если ей передан квадрат, и поэтому принцип открытости-закрытости можно считать нарушенным.
void g(Rectangle& r)
{
r.SetWidth(5);
r.SetHeight(4);
assert(r.GetArea()) == 20); // assertion will fail
}
И наоборот, если учесть, что тип фигуры должен ограничивать только соотношение ее размеров, то предположение в g() о том, что SetHeight будет изменять высоту и площадь, но не ширину, является недопустимым, а не только для настоящих квадратов, но даже потенциально для других прямоугольников, которые могут быть закодированы так, чтобы сохранять площадь или соотношение сторон при изменении высоты.
См. также
[ редактировать ]- Наследование (объектно-ориентированное программирование)
- Принцип замены Лискова (в объектно-ориентированном программировании )
- Подчинение
- Это-а
- Гипернимия (и супертип )
- Гипонимия (и подтип )
- Имеет-а
Примечания
[ редактировать ]- ^ «Подтипы и подклассы» (PDF) . MIT OCW . Проверено 2 октября 2012 г.
- ^ См. также «Сдерживание» (компьютерное программирование) .
- ^ Митчелл, Джон (2002). «10 «Концепции объектно-ориентированных языков» ». Понятия в языке программирования . Кембридж, Великобритания: Издательство Кембриджского университета. п. 287. ИСБН 0-521-78098-5 .
- ^ Гвидо ван Россум. «Подтипирование встроенных типов» . Проверено 2 октября 2012 г.
- ^ Лисков, Барбара (май 1988 г.). Абстракция данных и иерархия (PDF) . Уведомления SIGPLAN. Архивировано из оригинала 21 июня 2020 г.
{{cite book}}
: CS1 maint: неподходящий URL ( ссылка ) - ^ «Принцип замены Лискова» (PDF) . Роберт С. Мартин, 1996. Архивировано из оригинала (PDF) 5 сентября 2015 года . Проверено 2 октября 2012 г.
Ссылки
[ редактировать ]- Рональд Дж. Брахман ; « Что есть и чем не является IS-A. Анализ таксономических связей в семантических сетях ». Компьютер IEEE, 16 (10); Октябрь 1983 г.
- Жан-Люк Эно, Жан-Марк Хик, Винсент Энглеберт, Жан Анрард, Дидье Роланд: Понимание реализаций отношений IS-A . ЕР 1996: 42-57.