Saya baru belajar Java, dan saya bukan programmer yang berlatih.
Buku yang saya ikuti mengatakan bahwa ketika mengganti metode, tipe argumen harus sama, tetapi tipe yang dikembalikan dapat kompatibel secara polimorfik.
Pertanyaan saya adalah mengapa argumen tidak dapat diteruskan ke metode overriding bukan tipe subkelas dari tipe super yang diharapkan?
Dalam metode kelebihan beban, metode apa pun yang saya panggil pada objek dijamin akan didefinisikan pada objek.
Catatan tentang duplikat yang disarankan:
The Saran pertama tampaknya menjadi sekitar hirarki kelas dan di mana untuk menempatkan fungsi. Pertanyaan saya lebih fokus pada mengapa pembatasan bahasa ada.
The Saran kedua menjelaskan bagaimana melakukan apa yang saya minta, tapi tidak mengapa hal itu telah dilakukan dengan cara itu. Pertanyaan saya terfokus pada mengapa.
sumber
Jawaban:
Konsep yang awalnya Anda rujuk dalam pertanyaan Anda disebut tipe pengembalian kovarian .
Tipe kembalinya kovarian bekerja karena metode seharusnya mengembalikan objek tipe tertentu dan metode utama sebenarnya dapat mengembalikan subkelasnya. Berdasarkan aturan subtyping dari bahasa seperti Java, jika
S
merupakan subtipeT
, maka di mana punT
muncul kita bisa melewati aS
.Karena itu, aman untuk mengembalikan sebuah
S
ketika mengganti metode yang diharapkan aT
.Saran Anda untuk menerima bahwa metode penimpaan menggunakan argumen yang merupakan subtipe dari yang diminta oleh metode penimpaan jauh lebih rumit karena mengarah pada ketidakberesan dalam sistem tipe.
Di satu sisi, dengan aturan subtyping yang sama yang disebutkan di atas, kemungkinan besar itu sudah berfungsi untuk apa yang ingin Anda lakukan. Contohnya
Tidak ada yang mencegah implementasi kelas ini dari menerima hewan apa pun, karena sudah memenuhi kriteria dalam pertanyaan Anda.
Tetapi mari kita anggap kita dapat mengganti metode ini seperti yang Anda sarankan:
Inilah bagian yang lucu, sekarang Anda bisa melakukan ini:
Sesuai antarmuka publik
AnimalHunter
Anda harus dapat berburu binatang apa pun, tetapi sesuai penerapanMammutHunter
Anda, Anda hanya menerimaMammut
benda. Oleh karena itu metode overriden tidak memuaskan antarmuka publik. Kami baru saja mematahkan tingkat kesehatan sistem tipe di sini.Anda dapat menerapkan apa yang Anda inginkan dengan menggunakan obat generik.
Maka Anda bisa mendefinisikan MammutHunter Anda
Dan menggunakan kovarians generik dan contravariance, Anda dapat melonggarkan aturan yang menguntungkan Anda saat diperlukan. Misalnya kita bisa memastikan bahwa pemburu mamalia hanya bisa berburu kucing dalam konteks tertentu:
Seandainya
MammalHunter
alatAnimalHunter<Mammal>
.Dalam hal ini ini tidak akan diterima:
Bahkan ketika mamut adalah mamalia, ia tidak akan diterima karena pembatasan pada jenis contravarian yang kami gunakan di sini. Jadi, Anda masih dapat menjalankan beberapa kontrol atas jenis untuk melakukan hal-hal seperti yang Anda sebutkan.
sumber
Masalahnya bukan apa yang Anda lakukan dalam metode utama dengan objek yang diberikan sebagai argumen. Masalahnya adalah apa jenis argumen yang menggunakan kode metode Anda diizinkan untuk memberi makan ke metode Anda.
Metode penggantian harus memenuhi kontrak metode yang diganti. Jika metode yang ditimpa menerima argumen dari beberapa kelas dan Anda menimpanya dengan metode yang hanya menerima subkelas, itu tidak memenuhi kontrak. Itu sebabnya tidak valid.
Mengganti metode dengan tipe argumen yang lebih spesifik disebut overloading . Ini mendefinisikan metode dengan nama yang sama tetapi dengan jenis argumen yang berbeda atau lebih spesifik. Metode kelebihan beban tersedia di samping metode asli. Metode mana yang dipanggil tergantung pada jenis yang diketahui pada waktu kompilasi. Untuk membebani metode, Anda harus menghapus penjelasan @Override.
sumber