Anda sudah mendapatkan beberapa jawaban yang bagus, tetapi gajah besar di ruangan dalam pertanyaan Anda adalah yang ini:
mendengar dari seseorang bahwa menggunakan warisan harus dihindari, dan kita harus menggunakan antarmuka saja
Sebagai aturan praktis, ketika seseorang memberi Anda aturan praktis, maka abaikan saja. Ini tidak hanya berlaku untuk "seseorang memberi tahu Anda sesuatu", tetapi juga untuk membaca hal-hal di internet. Kecuali Anda tahu mengapa (dan dapat benar-benar berdiri di belakangnya), nasihat semacam itu tidak berharga dan seringkali sangat berbahaya.
Dalam pengalaman saya, konsep yang paling penting, dan membantu dalam OOP adalah "kopling rendah" dan "kohesi tinggi" (kelas / objek tahu sesedikit mungkin tentang satu sama lain, dan setiap unit bertanggung jawab atas sesedikit mungkin hal).
Kopling rendah
Ini berarti bahwa setiap "bundel barang" dalam kode Anda harus bergantung pada lingkungannya sesedikit mungkin. Ini berlaku untuk kelas (desain kelas) tetapi juga objek (implementasi aktual), "file" secara umum (yaitu, jumlah #include
s per satu.cpp
file , jumlah import
per .java
file tunggal dan sebagainya).
Tanda bahwa dua entitas digabungkan adalah bahwa salah satu dari mereka akan rusak (atau perlu diubah) ketika yang lain diubah dengan cara apa pun.
Warisan meningkatkan sambungan, jelas; mengubah kelas dasar mengubah semua subclass.
Antarmuka mengurangi kopling: dengan mendefinisikan kontrak berbasis metode yang jelas, Anda dapat mengubah apa pun tentang kedua sisi antarmuka secara bebas, selama Anda tidak mengubah kontrak. (Perhatikan bahwa "antarmuka" adalah konsep umum, interface
kelas abstrak Java atau C ++ hanyalah detail implementasi).
Kohesi Tinggi
Ini berarti setiap kelas, objek, file dll. Menjadi perhatian atau bertanggung jawab untuk sesedikit mungkin. Yaitu, hindari kelas besar yang melakukan banyak hal. Dalam contoh Anda, jika senjata Anda memiliki aspek yang benar-benar terpisah (amunisi, perilaku menembak, representasi grafis, representasi inventaris, dll.), Maka Anda dapat memiliki kelas berbeda yang mewakili tepat satu dari hal-hal itu. Kelas senjata utama kemudian berubah menjadi "pemegang" perincian itu; objek senjata kemudian sedikit lebih dari beberapa petunjuk untuk detail itu.
Dalam contoh ini, Anda akan memastikan bahwa kelas Anda yang mewakili "Perilaku Menembak" tahu sesedikit mungkin secara manusiawi tentang kelas senjata utama. Secara optimal, tidak ada sama sekali. Misalnya, ini berarti bahwa Anda dapat memberikan "Perilaku Menembak" ke objek apa pun di dunia Anda (menara, gunung berapi, NPC ...) hanya dengan satu jentikan jari. Jika suatu saat Anda ingin mengubah cara senjata direpresentasikan dalam inventaris, maka Anda dapat melakukannya - hanya kelas inventaris Anda yang mengetahui hal itu sama sekali.
Tanda bahwa suatu entitas tidak kohesif adalah jika ia tumbuh lebih besar dan lebih besar, bercabang ke beberapa arah secara bersamaan.
Warisan seperti yang Anda gambarkan mengurangi kohesi - kelas senjata Anda, pada akhirnya, adalah bongkahan besar yang menangani segala macam aspek yang berbeda, yang tidak terkait dengan senjata Anda.
Antarmuka secara tidak langsung meningkatkan kohesi dengan secara jelas memisahkan tanggung jawab antara kedua sisi antarmuka.
Apa yang harus dilakukan sekarang
Masih belum ada aturan yang keras dan cepat, semua ini hanyalah pedoman. Secara umum, sebagai pengguna TKK yang disebutkan dalam jawabannya, warisan diajarkan banyak di sekolah dan buku; itu adalah hal-hal mewah tentang OOP. Antarmuka mungkin lebih membosankan untuk diajarkan, dan juga (jika Anda melewati contoh-contoh sepele) sedikit lebih sulit, membuka bidang injeksi ketergantungan, yang tidak begitu jelas sebagai warisan.
Pada akhirnya, skema berbasis warisan Anda masih lebih baik daripada tidak memiliki desain OOP yang jelas. Jadi jangan ragu untuk tetap menggunakannya. Jika Anda mau, Anda dapat merenungkan / google sedikit tentang Kopling Rendah, Kohesi Tinggi dan lihat apakah Anda ingin menambahkan pemikiran semacam itu ke gudang senjata Anda. Anda selalu dapat menolak untuk mencobanya jika ingin, nanti; atau coba pendekatan berbasis antarmuka pada modul kode baru berikutnya yang lebih besar.