среда, декабря 07, 2005

is-a отношение

is-a отношение - это термин из теории объектно-ориентированного программирования. Кто-то считает, что этот термин не совсем корректный, да и вообще устаревший (В comp.object Роберт Мартин как-то бухтел по этому поводу). Но я натыкалась на него несколько раз, также как и на has-a. Про второе чуть позже, сегодня про is-a (иногда пишется ISA).
Если есть два объекта: A и B, то можно сказать, что B is-a A, если в программе везде, где используется A, можно использовать B. Несмотря на мудреное определение, все просто. Если у меня есть базовый класс CPrinter и я от него наследую CEpson, CHP и т.п., то логично будет чтобы функция, которая принимает в качестве параметра CPrinter, могла работать с любым отнаследованным принтером, поскольку по логике вещей CEpson is-a CPrinter.

Есть такое хорошее правило, если в программе есть публичное наследование, то оно должно являть собой is-a отношение. И это та вещь, которую компилятор не сделает автомагически, ответственность за то, чтобы публичное наследование было is-a отношением лежит на программисте. Например:

Если я где-то определила публичное наследование вида:
class CBase
{
public:
virtual void VirtFunc();
// ...
};

class CDerived : public CBase
{
public:
virtual void VirtFunc();
// ...
};

void SomeFunc( const CBase& );


То я фактически говорю, что CDerived is-a CBase, а значит, что в функцию SomeFunc можно передавать как экземпляры CDerived, так и CBase, и они должны обрабатываться корректно. А если я реализовала функцию VirtFunc таким образом, что передавать в SomeFunc экземпляр CDerived по каким-либо причинам нельзя, то это как минимум странно.


Ссылки по теме:
comp.object IS A and HAS A relationships
GotW #40: Controlled Polymorphism

1 коммент.:

qosys комментирует...

Еще есть принцип LSP, который как раз и приводит к правилу is-a.

Принцип подстановки Лисков — Википедия.