Saya sedang mengerjakan contoh kode dari bab Traits in Programming in Scala Edition1 https://www.artima.com/pins1ed/traits.html
dan menemukan perilaku aneh karena kesalahan ketik saya. Sementara override metode sifat di bawah ini potongan kode tidak memberikan kesalahan kompilasi meskipun jenis kembalinya metode ditimpa berbeda Unit
vs String
. Tetapi setelah memanggil metode pada objek, ia mengembalikan Unit tetapi tidak mencetak apa pun.
trait Philosophical {
def philosophize = println("I consume memory, therefore I am!")
}
class Frog extends Philosophical {
override def toString = "green"
override def philosophize = "It aint easy to be " + toString + "!"
}
val frog = new Frog
//frog: Frog = green
frog.philosophize
// no message printed on console
val f = frog.philosophize
//f: Unit = ()
Tetapi ketika saya memberikan tipe pengembalian eksplisit dalam metode yang diganti, itu memberikan kesalahan kompilasi:
class Frog extends Philosophical {
override def toString = "green"
override def philosophize: String = "It aint easy to be " + toString + "!"
}
override def philosophize: String = "It aint easy to be " + toString +
^
On line 3: error: incompatible type in overriding
def philosophize: Unit (defined in trait Philosophical);
found : => String
required: => Unit
Adakah yang bisa membantu menjelaskan mengapa tidak ada kesalahan kompilasi dalam kasus pertama.
scala
overriding
traits
Shanil
sumber
sumber
Jawaban:
Ketika jenis yang diharapkan adalah
Unit
, nilai apa pun dapat diterima :sumber
Ketika Anda tidak menentukan jenis pengembalian secara eksplisit itu disimpulkan oleh jenis itu perlu memiliki untuk
override
bekerja.Itu ternyata
Unit
.Karena
String
nilai (nilai ekspresi yang membentuk fungsi tubuh) dapat ditugaskanUnit
, kompiler senang.sumber
String
ditolak. Di Jawa (dan saya pikir dalam Scala, juga), Anda diizinkan untuk mempersempit tipe pengembalian saat menimpa. Misalnya, ketika metode induk kembaliNumber
, Anda dapat kembaliInteger
. Mungkinvoid
/Unit
khusus.trait Philosophical { def philosophize : Number = 1 } class Frog extends Philosophical { override def philosophize : Integer = 2 }
String
untukUnit
lebih seperti yang kedua, bahkan jika itu tidak persis seperti itu.Frog
:def philosophize : Integer
dandef philosophize : Number
. Yang kedua sebenarnya mengesampingkanPhilosophical
metode (dan memanggil yang pertama). Hal yang sama pasti bisa dilakukan untukvoid
/ hal lain, para desainer hanya memutuskan untuk tidak melakukannya.