Jika sifat A memanjang B, maka mencampurkan dalam A memberi Anda tepat B ditambah apa pun yang ditambahkan atau diperluas oleh A. Sebaliknya, jika sifat A memiliki referensi diri yang secara eksplisit diketik sebagai B, maka kelas induk akhir juga harus dicampur dalam B atau tipe B turunan (dan mencampurnya terlebih dahulu , yang penting).
Itulah perbedaan terpenting. Dalam kasus pertama, tipe B yang tepat dikristalisasi pada titik A yang meluas. Pada yang kedua, perancang kelas induk dapat memutuskan versi B yang digunakan, pada titik di mana kelas induk disusun.
Perbedaan lainnya adalah di mana A dan B menyediakan metode dengan nama yang sama. Di mana A meluas B, metode A menimpa B. Di mana A dicampur setelah B, metode A hanya menang.
Referensi diri yang diketik memberi Anda lebih banyak kebebasan; kopling antara A dan B longgar.
MEMPERBARUI:
Karena Anda tidak jelas tentang manfaat perbedaan ini ...
Jika Anda menggunakan pewarisan langsung, maka Anda membuat sifat A yang merupakan B + A. Anda telah mengatur hubungan di atas batu.
Jika Anda menggunakan referensi diri yang diketik, maka siapa pun yang ingin menggunakan sifat A Anda di kelas C bisa
- Campur B dan A menjadi C.
- Campur subtipe B dan kemudian A menjadi C.
- Campur A menjadi C, di mana C adalah subkelas dari B.
Dan ini bukan batas dari pilihan mereka, mengingat cara Scala memungkinkan Anda untuk instantiate sifat secara langsung dengan blok kode sebagai konstruktornya.
Adapun perbedaan antara metode menang A, karena A dicampur pada akhirnya, dibandingkan dengan A memperluas B, pertimbangkan ini ...
Di mana Anda mencampur dalam urutan sifat, setiap kali metode foo()
dipanggil, kompilator pergi ke sifat terakhir yang dicampur untuk mencari foo()
, lalu (jika tidak ditemukan), itu melintasi urutan ke kiri sampai menemukan sifat yang mengimplementasikan foo()
dan menggunakan bahwa. A juga memiliki opsi untuk memanggil super.foo()
, yang juga melintasi urutan ke kiri hingga menemukan implementasi, dan seterusnya.
Jadi jika A memiliki referensi diri yang diketik untuk B dan penulis A tahu bahwa B mengimplementasikan foo()
, A dapat memanggil super.foo()
mengetahui bahwa jika tidak ada yang lain menyediakan foo()
, B akan melakukannya. Namun, pencipta kelas C memiliki opsi untuk menghapus semua sifat lain yang diimplementasikan foo()
, dan A akan mendapatkannya.
Sekali lagi, ini jauh lebih kuat dan tidak terlalu membatasi daripada A memperluas B dan langsung memanggil versi B dari foo()
.