2009-06-08 4 views
3

В книге, он говоритКогда класс B наследует от класса A, должно быть, «класс B - это класс A»?

класс Name имеет свойство фамилии и имени.

Адрес наследует от Название и имеет дополнительное имущество с номером улицы, название улицы, города, штата, почтовый индекс.

Это, кажется, отличается от других случаев, когда

Cat наследует от животных, и кот "есть-" Animal.

Является ли это обязательным условием «является-a» для хорошего дизайна объекта? Должен ли адрес наследовать от имени?

Update:, так как некоторые пользователи попросили источник: alt text http://img192.imageshack.us/img192/8903/learningrubyp133smaller.png

+16

Плохая книга. Классический пример злоупотребления наследованием. –

+1

Не могли бы вы предоставить название и автор книги? Это кажется странным дизайнерским решением. Вы уверены, что у вас есть правильный контекст? –

+1

Learning Ruby, стр.133, O'Reilly 2007 –

ответ

13

Нет, я не думаю, что этот адрес должен наследовать от имени. Они не имеют ничего общего, кроме одного поля строки. Адрес не должен иметь фамилию.

Inherritance следует использовать только в тех случаях, когда существует четкое и четкое отношение, когда какое-либо поведение расширено.

Следует придерживаться композиции по наследству, поскольку она позволяет свободно связываться и динамически изменять поведение.

+0

Вы также можете использовать наследование для повторного использования кода, но это быстро генерирует глубокие иерархии, которые являются запахом кода. Поэтому я бы не советовал это делать. –

+1

+1 для композиции в этом случае. Расширение имени, чтобы стать адресом, определенно неверно. – Joey

4

Да, наследование является именно для "есть-" отношения. В случае с именем и адресом было бы более элегантно иметь составной класс Person, который имеет переменные-члены типов Name и Address.

Но для случаев, когда действительно каждая сущность класса Address также обладает теми же свойствами, что и наследование класса Name. Опять же, это зависит от того, как это будет работать в реальной проблеме, это не общий вопрос.

4

В этом случае ваша книга злоупотребляет объектной ориентацией, чтобы сохранить необходимость переопределения нескольких переменных. Понятно, что это просто неверно, что адрес «is-a» Name. Было бы более естественным, если бы объект Address содержал ссылку на объект Name (резидент в указанном адресе).

2

Да. Когда ваш класс B является классом A, вы можете использовать наследование. То есть, в таких ситуациях вполне допустимо, чтобы класс B был подклассом класса A.

В ситуациях, когда это отношение не ясно, вы должны рассматривать композицию вместо наследования. (имеет отношение вместо отношения is-a).

То есть, пример в вашей книге кажется неправильным. Адрес не является именем. У адреса может быть имя, поэтому его следует использовать.

2

Если класс B можно использовать там, где ожидается класс A, то у вас есть «is-a» наследование (см. Liskov substitution principle). В противном случае вы просто расширяете класс с новым поведением.

Адрес может наследоваться от имени класса (я не согласен), но вы не должны относиться к как к имени.

2

В общем случае: если класс D наследует от класса B, то D является Б.

В C++: если класс D наследует частной из класса B, то D не является Б, так как никто не знает. Страуструп думает об этом как о альтернативе композиции. Я считаю это одной из ошибок в дизайне C++ именно по той причине, что, по моему мнению, «наследует» должно быть синонимом «есть».

Смежные вопросы