Das Schlüsselwort with in Scala
Dieser Artikel zeigt, wie man das Schlüsselwort with
in Scala verwendet.
Verwenden Sie das Schlüsselwort with
in Scala
Dieses Schlüsselwort wird normalerweise verwendet, wenn es um Klassenkompositionen mit Mixins geht. Mixins sind Merkmale, die verwendet werden, um eine Klasse zusammenzustellen.
Dies ähnelt in gewisser Weise einer Java-Klasse, die eine Schnittstelle implementieren kann.
Sehen wir uns ein Beispiel an, um das Schlüsselwort with
besser zu verstehen:
abstract class vehicle {
val message: String
}
class Car extends vehicle {
val message = "I'm an instance of class vehicle"
}
trait sportsCar extends vehicle {
def ourMessage = message.toUpperCase()
}
class temp extends Car with sportsCar
val obj = new temp
println(obj.message) // I'm an instance of class vehicle
println(obj.ourMessage) // I'M AN INSTANCE OF CLASS VEHICLE
Im obigen Code hat die Klasse temp
die Superklasse Car
und mixin sportsCar
. Eine Klasse kann nur eine Oberklasse, aber viele Mixins mit dem Schlüsselwort with
erweitern; eine Superklasse und Mixins können denselben Supertyp
haben.
Schauen wir uns ein anderes Beispiel an. Lassen Sie uns zunächst eine abstrakte Klasse mit einem Typ T
und einigen Standard-Iteratormethoden erstellen.
abstract class ourIterator {
type T
def hasNext: Boolean
def next(): T
}
Lassen Sie uns nun eine konkrete Klasse erstellen, in der alle Implementierungen der abstrakten Mitglieder von T
, nämlich hasNext
und next
, vorhanden sind.
class StringIterator(str: String) extends ourIterator {
type T = Char
private var i = 0
def hasNext = i < str.length
def next() =
{
val ch = str.charAt(i)
i += 1
ch
}
}
Lassen Sie uns ein Trait erstellen, das auch die Klasse ourIterator
erweitert.
trait anotherIterator extends ourIterator {
def foreach(X: T => Unit): Unit = while (hasNext) X(next())
}
Das Trait anotherIterator
implementiert die foreach()
-Methode, die die Funktion X: T => Unit
kontinuierlich auf das nächste Element next()
aufruft, solange es weitere Elemente gibt while(hasNext)
.
Da anotherIterator
ein Trait ist, muss es keine abstrakten Member der ourIterator
-Klasse implementieren. Jetzt können wir die Funktionalitäten von anotherIterator
und StringIterator
in einer einzigen Klasse kombinieren, wie unten gezeigt:
class temp extends StringIterator("Tony") with anotherIterator
val obj = new temp
obj.foreach(println)
Vollständiger Arbeitscode:
abstract class ourIterator {
type T
def hasNext: Boolean
def next(): T
}
class StringIterator(str: String) extends ourIterator {
type T = Char
private var i = 0
def hasNext = i < str.length
def next() =
{
val ch = str.charAt(i)
i += 1
ch
}
}
trait anotherIterator extends ourIterator {
def foreach(X: T => Unit): Unit = while (hasNext) X(next())
}
class temp extends StringIterator("Tony") with anotherIterator
val obj = new temp
obj.foreach(println)
Ausgang:
T
o
n
y
Im obigen Code hat die neue Klasse temp
StringIterator
als superclass
und anotherIterator
als Mixin. Nur mit Einfachvererbung ist dieses Maß an Flexibilität nicht zu erreichen.