Я понимаю основы наследования, но этот смущает меня. Как был бы Вы идти о высказывании:
Мой текущий код только только позволит одну песню на объект:
class Song extends Album{}
class Album extends Artist{}
Я уверен, что пропускаю что-то важное. Какие-либо мысли?
Я делаю это в PHP
Альбом содержит один или несколько объектов-исполнителей. Наследование будет означать, что альбом является исполнителем. Вам нужно (EDIT) агрегирование:
class Album
{
public $artists = array(); // Array of Artist instances
public $songs = array(); // Array of Song instances
}
агрегирование означает, что каждый исполнитель и экземпляр песни могут принадлежать другим альбомам. В случае композиции исполнитель или песня могут принадлежать к одному альбому.
] Если вы сообщите нам, чего вы хотите достичь, это может помочь нам прийти к правильному ответу. Однако, эти связи обычно хранятся в вашей базе данных.[
].Не используйте наследование для такого рода отношений, ради всего, что зажарено и залито восхитительными сливками!
Песня не является продолжением альбома, это часть альбома. Точно так же альбом - это не продолжение исполнителя, он создан художником. Более того, песня может появиться в нескольких альбомах, а в одном альбоме может быть несколько исполнителей.
В этой ситуации вы должны использовать отношение типа «есть-а» вместо наследования. Например, у вас может быть объект Album, в состав которого входит массив объектов Song. Это передало бы идею о том, что песни принадлежат альбомам надлежащим образом.
Как я упоминал в одном из своих комментариев, если бы вам пришлось моделировать его через ООП, я бы сказал,
class Song {
string[] artists;
string title;
int genre;
}
class Album {
Song[] tracks;
}
Попробуйте подумать об этом с точки зрения того, какие объекты и какие свойства обладают. Т.е. «Автомобиль ИМЕЕТ цвет» или «Воздушный шар ИМЕЕТ нитку».
Song HAS Artist
Album HAS Songs
Таким образом, ваш класс Song будет иметь объект Artist, а ваш класс Album будет содержать коллекцию объектов Song.
Я не думаю, что есть какое-либо наследство в этих трех классах. Песня альбом? Нет, я не думаю, что это так песню не должна наследовать из альбома. Альбом художник? Нет, я не думаю, что это либо такой альбом не должен наследовать от художника.
вместо этого вы хотите посмотреть на инкапсуляцию. Альбом ссылается на нулю или более художников. Альбом содержит ноль руды больше песен. Художник ссылается на нулевые или новые альбомы.
Я не уверен, что вы правильно используете ООП. Обычно объект расширяет родительский объект, если он имеет те же функциональные возможности, что и этот родительский объект, но имеет некоторые дополнительные (или специфические) функциональные возможности.
Например, давайте возьмем автомобильную промышленность:
class Automobile {}
class Truck extends Automobile {}
class Car extends Automobile {}
class Lexus extends Car{}
Посмотрите, насколько Lexus наиболее специфичен, поэтому он выстраивает иерархию по мере продвижения вверх?
То, что вы хотите, похоже на отношения has_many. У исполнителя много альбомов, в альбоме много песен и т. Д.
Edit 1: Как Виктор Николет сказал, вам нужна композиция .
Редактировать 2: Как указано в комментариях, вам действительно нужна агрегация . Предоставленная статья объясняет разницу между ними.
Если я вас правильно понимаю, вы спрашиваете об избежании преждевременной пессимизации , хорошего дополнения к избежанию преждевременной оптимизации. То, что следует избегать, основанная на моем опыте, не копирует большие объекты, когда это возможно. Это включает в себя:
Эта последняя пуля требует некоторого объяснения Отказ Я не могу сказать вам, сколько раз я видел это:
class Foo
{
const BigObject & bar();
};
// ... somewhere in code ...
BigObject obj = foo.bar(); // OOPS! This creates a copy!
правильный путь:
const BigOject &obj = foo.bar(); // does not create a copy
Эти рекомендации применяются к чему больше, чем умного указателя или встроенного типа. Кроме того, я настоятельно рекомендую инвестировать время обучения на профиля вашего кода . Хороший профилированный инструмент поможет поймать расточительные операции.
-121--1069254-о пользу состава на наследство.
тем, что вы сказали, что это должно быть похоже на:
Объект альбома имеет один или несколько объектов художника. Объект альбома имеет одну или несколько объектов песни
Альбом класса { Художник [] художники; Песня [] песни; }
Однако это не совсем так, как я представляю это. Я думаю, что каждый альбом имеет одну или несколько песен, которые выполняются одним или несколькими артистами. Я бы сделал это как:
класс альбома { Песни [] песни; // Другие специальные свойства альбома }
Ученая песня { Художник [] художники; // Другие специфические свойства песни }
Артист класса { // Специфика художника }
И я настоятельно рекомендую при взгляде на принципы OOD.
Вот мой взгляд.
Альбом содержит песню, но песня не является альбомом.
Альбом связан с художником (ыми), но альбом не является художником.
Вы смешиваете наследство с отношениями.
Это звучит как вопрос моделирования базы данных, а не один из OOP. Это потому, что у вас, скорее всего, у вас будет база данных песен художников и альбомов. Не классовая иерархия.
отношение наследования называется "IS-A", в то время как отношение, которое вы ищете, является HAS-A
Вам нужно что-то вроде этого:
Album
artists: Artist[1..*]
songs : Song[1..*]
Где альбом HAS от 1 до многих ( * ) исполнителей ( определенных массивом Artist ) и 1 альбом имеет от 1 до многих ( * ) композиций ( определенных массивом Song )
.