Они совершенно разные. Наследование - это отношение "is-a" . Композиция представляет собой «has-a» .
Вы выполняете композицию, имея экземпляр другого класса C
в качестве поля вашего класса, вместо расширения C
. Хорошим примером, где состав был бы намного лучше, чем наследование, является java.util.Stack
, который в настоящее время распространяется java.util.Vector
. Это сейчас считается ошибкой. Стек "- это-НЕ-a" вектор; вам не разрешается вставлять и удалять элементы произвольно. Это должно было быть композиция.
К сожалению, слишком поздно исправить эту ошибку дизайна, так как изменение иерархии наследования теперь нарушит совместимость с существующим кодом. Если вместо наследования использовалась композиция Stack
, ее всегда можно было изменить, чтобы использовать другую структуру данных, не нарушая API .
Я очень рекомендую книгу Джоша Блоха Эффективная Java 2-е издание
Хороший объектно-ориентированный дизайн - это не либеральное расширение существующих классов. Ваш первый инстинкт должен составлять вместо этого.
См. Также:
Вместо этого используйте Groovy Traits:
http://docs.groovy-lang.org/next/html/documentation/core-traits.html
trait Person1 {
String name
static constraints = { name nullable : true }
static mapping = {
table 'PERSON'
name column : 'PERSON_NAME'
}
}
class Person2 implements Person1 {
String address
static constraints = { address nullable : true }
static mapping = {
name address : 'PERSON_ADD'
}
}