Ich habe die Codebeispiele aus dem Kapitel über Merkmale in der Programmierung in Scala Edition1 https://www.artima.com/pins1ed/traits.html durchgearbeitet
und stieß wegen meines Tippfehlers auf ein komisches Verhalten. Während zwingende Methode eines Merkmal unter Code - Schnipsel gibt keine Kompilierung - Fehler , obwohl die Rückgabetypen der überschriebenen Methode unterscheidet Unit
vs String
. Beim Aufrufen der Methode für ein Objekt wird Unit zurückgegeben, es wird jedoch nichts gedruckt.
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 = ()
Wenn ich jedoch den expliziten Rückgabetyp in der überschriebenen Methode gebe, wird ein Kompilierungsfehler ausgegeben:
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
Kann mir jemand erklären, warum im ersten Fall kein Kompilierungsfehler vorliegt.
scala
overriding
traits
Shanil
quelle
quelle
Antworten:
Wenn der erwartete Typ ist
Unit
, kann jeder Wert akzeptiert werden :quelle
Wenn Sie den Rückgabetyp nicht explizit angegeben haben, wurde er von dem Typ abgeleitet, den er für den benötigt
override
er funktioniert.Das stellte sich heraus
Unit
.Da
String
Werte (der Wert des Ausdrucks, aus dem der Funktionskörper besteht) zugewiesen werden können,Unit
ist der Compiler zufrieden.quelle
String
abgelehnt wurde. In Java (und ich denke , in Scala, auch), dürfen Sie verengen den Rückgabetyp beim Überschreiben. Wenn beispielsweise die übergeordnete Methode zurückgegeben wirdNumber
, können Sie zurückkehrenInteger
. Vielleichtvoid
/Unit
ist etwas Besonderes.trait Philosophical { def philosophize : Number = 1 } class Frog extends Philosophical { override def philosophize : Integer = 2 }
String
toUnit
ist eher wie das zweite, auch wenn es nicht genau ist das ist.Frog
:def philosophize : Integer
unddef philosophize : Number
. Der zweite überschreibt tatsächlich diePhilosophical
Methode Methode der (und ruft die erste auf). Das gleiche könnte sicherlich fürvoid
/ alles andere getan werden , die Designer haben einfach beschlossen, es nicht zu tun.