Das Schlüsselwort with in Scala

Suraj P 21 Juni 2023
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.

Autor: Suraj P
Suraj P avatar Suraj P avatar

A technophile and a Big Data developer by passion. Loves developing advance C++ and Java applications in free time works as SME at Chegg where I help students with there doubts and assignments in the field of Computer Science.

LinkedIn GitHub