Saya menyukai jawaban dari Roland Ewald karena ia menggambarkan dengan penggunaan yang sangat sederhana alias tipe, dan untuk lebih detail memperkenalkan tutorial yang sangat bagus. Namun, karena use case lain diperkenalkan di posting ini bernama type member , saya ingin menyebutkan use case paling praktis darinya, yang sangat saya sukai: (bagian ini diambil dari sini :)
Tipe Abstrak:
type T
T di atas mengatakan bahwa jenis ini yang akan digunakan, belum diketahui, dan tergantung pada subkelas beton, itu akan ditentukan. Cara terbaik untuk memahami konsep pemrograman adalah dengan memberikan contoh: Misalkan Anda memiliki skenario berikut:
Di sini Anda akan mendapatkan kesalahan kompilasi, karena metode makan di kelas Cow dan Tiger tidak menimpa metode makan di kelas Hewan, karena tipe parameternya berbeda. Ini Rumput di kelas Sapi, dan Daging di kelas Harimau vs Makanan di kelas Hewan yang super kelas dan semua subclass harus sesuai.
Sekarang kembali ke mengetik abstraksi, dengan diagram berikut dan hanya menambahkan abstraksi jenis, Anda dapat menentukan jenis input, dalam subkelas sesuai itu sendiri.
Sekarang lihat kode-kode berikut:
val cow1: Cow = new Cow
val cow2: Cow = new Cow
cow1 eat new cow1.SuitableFood
cow2 eat new cow1.SuitableFood
val tiger: Tiger = new Tiger
cow1 eat new tiger.SuitableFood // Compiler error
Kompiler senang dan kami meningkatkan desain kami. Kita bisa memberi makan sapi kita dengan sapi. Makanan yang cocok dan penyusun mencegah kita memberi makan sapi dengan makanan yang cocok untuk Harimau. Tetapi bagaimana jika kita ingin membuat perbedaan antara jenis cow1 CocokFood dan cow2 SuitabeFood. Dengan kata lain, akan sangat berguna dalam beberapa skenario jika jalur yang kita gunakan untuk mengetik (tentu saja melalui objek) pada dasarnya penting. Berkat fitur-fitur canggih dalam scala, dimungkinkan:
Tipe ketergantungan jalur:
Objek scala dapat memiliki tipe sebagai anggota. Arti jenisnya, tergantung pada jalur yang Anda gunakan untuk mengaksesnya. Path ditentukan oleh referensi ke objek (alias turunan dari sebuah kelas). Untuk menerapkan skenario ini, Anda perlu mendefinisikan kelas Grass di dalam Sapi, yaitu, Sapi adalah kelas luar dan Rumput adalah kelas dalam. Strukturnya akan seperti ini:
class Cow extends Animal {
class Grass extends Food
type SuitableFood = Grass
override def eat(food: this.SuitableFood): Unit = {}
}
class Tiger extends Animal {
class Meat extends Food
type SuitableFood = Meat
override def eat(food: this.SuitableFood): Unit = {}
}
Sekarang jika Anda mencoba untuk mengkompilasi kode ini:
1. val cow1: Cow = new Cow
2. val cow2: Cow = new Cow
3. cow1 eat new cow1.SuitableFood
4. cow2 eat new cow1.SuitableFood // compilation error
Pada baris 4 Anda akan melihat kesalahan karena Rumput sekarang menjadi kelas bagian dalam Sapi, oleh karena itu, untuk membuat turunan Rumput, kita memerlukan objek sapi dan objek sapi ini menentukan jalurnya. Jadi 2 objek sapi memunculkan 2 jalur berbeda. Dalam skenario ini, cow2 hanya ingin makan makanan yang khusus dibuat untuk itu. Begitu:
cow2 eat new cow2.SuitableFood
Sekarang semua orang senang :-)