Saya mengambil kursus coursera Martin Odersky tentang pemrograman fungsional dengan scala, dan untuk saat ini saya telah belajar dua hal yang bersama-sama tidak masuk akal:
- Scala tidak mendukung banyak pewarisan
Nothing
adalah subtipe dari setiap tipe lainnya
Kedua pernyataan ini tidak bisa hidup bersama, jadi bagaimana tepatnya hal ini dilakukan? dan apa sebenarnya arti dari "subtipe dari setiap tipe lain"
Edit 1
Dalam Scala API , Nothing
didefinisikan sebagai abstract final class Nothing extends Any
... jadi bagaimana ia dapat memperluas kelas lain?
programming-languages
scala
vainolo
sumber
sumber
Nothing
adalah subkelas dari setiap kelas lainnya. Ia mengatakan bahwa ini adalah subtipe dari setiap tipe lainnya .Jawaban:
Subtyping dan pewarisan adalah dua hal yang berbeda!
Nothing
tidak memperpanjang segalanya, ini subtipe , hanya meluasAny
.The spesifikasi [§3.5.2] memiliki kasus khusus yang mengatur subtyping-hubungan
Nothing
:Dimana
<:
pada dasarnya berarti "adalah subtipe dari".Adapun cara ini dilakukan: Kami tidak tahu, itu adalah kompiler sihir dan detail implementasi.
Cukup sering bahasa melakukan hal-hal yang Anda sebagai programmer tidak bisa. Sebagai mitra untuk
Nothing
: Segala sesuatu di Scala mewarisi dariAny
, semuanya kecualiAny
. Mengapa tidakAny
mewarisi sesuatu? Kamu tidak bisa melakukan itu Mengapa Scala bisa melakukan itu? Nah, karena Scala yang menetapkan aturan, bukan Anda.Nothing
menjadi subtipe dari segala sesuatu hanyalah contoh lain dari ini.sumber
null
ditugaskan untuk bidang dari setiap jenis di Jawa. Mengapa itu mungkin? Apakahnull
instance dari setiap kelas? Tidak, ini mungkin karena kompiler mengatakannya. Titik.extends
di Jawa, dan tidak sebagai komposisi ) Anda melakukannya untuk subtyping setelah semua.Ketika dia mengatakan bahwa Scala tidak mendukung multiple inheritance, maka dia merujuk pada pewarisan implementasi metode beberapa kali. Tentu saja, Anda dapat mengimplementasikan beberapa antarmuka / sifat dalam sebuah kelas, dan mereka bahkan dapat mendefinisikan metode yang sama, tetapi Anda tidak mendapatkan konflik antara implementasi yang berbeda karena linierisasi sifat.
Secara umum, jika Anda memiliki kelas
C1
dengan metodef()
dan kelasC2
juga dengan metodef()
, maka multiple inheritance berarti Anda dapat mewarisi kedua implementasi darif()
. Ini dapat menyebabkan berbagai masalah, yang diselesaikan Scala dengan hanya membiarkan Anda mewarisi dari satu kelas dan dalam kasus beberapa sifat dengan memilih satu implementasi berdasarkan urutan sifat tersebut.Adapun
Nothing
hal-hal yang sangat sederhana, karena tidak ada yang tidak memiliki atribut atau metode yang ditentukan. Jadi, Anda tidak dapat memiliki konflik warisan. Tetapi saya berasumsi bahwa sebagian besar kejutan Anda berasal dari pemahaman yang berbeda tentang pewarisan berganda.Setelah Anda memahami bahwa linierisasi sifat secara efektif menghilangkan segala ambiguitas warisan, dan bahwa kami tidak menyebut mewarisi dari banyak sifat sebagai warisan ganda karena itu, maka Anda harus baik-baik saja.
Mengenai bagaimana ini direalisasikan: kompiler pada akhirnya bertanggung jawab untuk ini. Lihat bagian spesifikasi bahasa Scala 3.5.2 kesesuaian, yang antara properti lainnya termasuk:
Atau dengan kata lain, jika Anda ingin mengimplementasikan kompiler dengan benar, ia harus menangani
Nothing
sebagai subtipe dari segalanya berdasarkan spesifikasi. Untuk alasan yang jelas,Nothing
tidak didefinisikan untuk memperluas dari semua kelas yang dimuat ke dalam sistem, tetapi relevansi mendefinisikanNothing
sebagai subtipe terbatas pada semua tempat, di mana subtyping relevan.Poin penting di sini adalah bahwa tidak ada contoh tipe
Nothing
, oleh karena itu, perawatannya terbatas hanya untuk pemeriksaan tipe, yang semuanya ada di ranah kompiler.sumber