Ви вже отримали кілька приємних відповідей, але величезний слон у кімнаті у вашому запитанні такий:
чути від когось, що слід уникати використання успадкування, а нам слід використовувати інтерфейси
Як правило, коли хтось дає вам правило, ігноруйте його. Це стосується не лише того, що "хтось вам щось скаже", а й для читання матеріалів в Інтернеті. Якщо ви не знаєте чому (і справді може стояти за цим), така порада нікчемна і часто дуже шкідлива.
На мій досвід, найважливіші та корисні поняття в ООП - це "низька зв'язок" і "висока згуртованість" (класи / об'єкти знають якомога менше один про одного, і кожен підрозділ відповідає за якомога менше речей).
Низька муфта
Це означає, що будь-яка «пачка речей» у вашому коді повинна якомога менше залежати від оточення. Це стосується класів (дизайн класу), але також об'єктів (фактична реалізація), "файлів" взагалі (тобто, кількість #include
s на один .cpp
файл, кількість import
одного .java
файлу тощо).
Ознакою того, що два об'єднання пов'язані, є те, що одна з них зламається (або потрібно змінити), коли інша буде змінена будь-яким чином.
Спадщина збільшує зв'язок, очевидно; зміна базового класу змінює всі підкласи.
Інтерфейси зменшують зв'язок: визначаючи чіткий, заснований на методах договір, ви можете вільно змінити що-небудь про обидві сторони інтерфейсу, доки ви не зміните договір. (Зауважте, що "інтерфейс" є загальним поняттям, interface
абстрактні класи Java або C ++ - це лише деталі реалізації).
Висока згуртованість
Це означає, щоб кожен клас, об’єкт, файл тощо займався або відповідав за нього якнайменше. Тобто уникайте великих класів, які роблять багато чого. У вашому прикладі, якщо ваша зброя має абсолютно окремі аспекти (боєприпаси, поведінка при стрільбі, графічне зображення, подання інвентаря тощо), то у вас можуть бути різні класи, які представляють саме одну з цих речей. Потім основний клас зброї перетворюється на "власника" цих деталей; об'єкт зброї тоді трохи більше, ніж кілька покажчиків на ці деталі.
У цьому прикладі ви переконаєтесь, що ваш клас, що представляє "вогнепальну поведінку", знає якомога менше людського про основний клас зброї. Оптимально, взагалі нічого. Це, наприклад, означатиме, що ви можете надати "Поведінка вогню" будь-якому об'єкту у вашому світі (башти, вулкани, NPC ...) лише одним пальцем. Якщо ви в якийсь момент хочете змінити, як зброя представлена в інвентарі, тоді ви можете це зробити просто - про це взагалі знає лише ваш інвентарний клас.
Ознакою того, що суб'єкт господарювання не є згуртованим, є, якщо воно зростає все більше і більше, розгалужуючись в декілька напрямків одночасно.
Наслідування, як ви описуєте, зменшує згуртованість - наприкінці дня ваші заняття зброєю - це великі шматки, які обробляють усілякі різні, не пов'язані з вами аспекти вашої зброї.
Інтерфейси опосередковано збільшують згуртованість, чітко розподіляючи обов'язки між двома сторонами інтерфейсу.
Що ж тепер робити
Досі немає жорстких і швидких правил, все це лише вказівки. Загалом, як згадував у своїй відповіді користувач TKK, про спадкування багато навчають у школі та книгах; це модні речі про OOP. Інтерфейси, ймовірно, є більш нудними для навчання, а також (якщо пройти повз банальних прикладів) трохи складніше, відкриваючи поле введення залежності, що не так чітко, як успадкування.
Зрештою, схема, заснована на спадщині, все ще краща, ніж взагалі не має чіткого дизайну ООП. Тож сміливо дотримуйтесь цього. Якщо ви хочете, ви можете поскаржити / google трохи про низьку з’єднаність, високу згуртованість і побачити, чи хочете ви додати такого типу мислення до свого арсеналу. Ви завжди можете спробувати це випробувати, якщо хочете, пізніше; або спробуйте підходи, засновані на інтерфейсі, для наступного нового нового модуля коду.