Unterschied zwischen Objekt und Klasse in Scala

635

Ich gehe gerade einige Scala-Tutorials im Internet durch und habe in einigen Beispielen festgestellt, dass zu Beginn des Beispiels ein Objekt deklariert ist.

Was ist der Unterschied zwischen classund objectin Scala?

Steve
quelle

Antworten:

578

tl; dr

  • class C definiert eine Klasse, genau wie in Java oder C ++.
  • object Oerstellt ein Singleton- Objekt Oals Instanz einer anonymen Klasse; Es kann verwendet werden, um statische Elemente zu speichern, die nicht mit Instanzen einer Klasse verknüpft sind.
  • object O extends Tmacht das Objekt zu Oeiner Instanz von trait T; Sie können dann Oüberall passieren , ein Twird erwartet.
  • Wenn es ein gibt class C, dann object Cist es das Begleitobjekt der Klasse C. Beachten Sie, dass das Begleitobjekt nicht automatisch eine Instanz von ist C.

Siehe auch Scala-Dokumentation für Objekt und Klasse .

object als Host von statischen Mitgliedern

In den meisten objectFällen müssen Sie Methoden und Werte / Variablen enthalten, die verfügbar sein sollen, ohne zuvor eine Instanz einer Klasse instanziieren zu müssen. Diese Verwendung ist eng mit staticMitgliedern in Java verbunden.

object A {
  def twice(i: Int): Int = 2*i
}

Sie können dann die obige Methode mit aufrufen A.twice(2).

Wenn Sie twiceMitglied einer Klasse Awären, müssten Sie zuerst eine Instanz erstellen:

class A() {
  def twice(i: Int): Int = 2 * i
}

val a = new A()
a.twice(2)

Sie können sehen, wie redundant dies ist, da twicekeine instanzspezifischen Daten erforderlich sind.

object als spezielle benannte Instanz

Sie können das objectselbst auch als spezielle Instanz einer Klasse oder eines Merkmals verwenden. Wenn Sie dies tun, muss Ihr Objekt einige traiterweitern, um eine Instanz einer Unterklasse davon zu werden.

Betrachten Sie den folgenden Code:

object A extends B with C {
  ...
}

Diese Deklaration deklariert zuerst eine anonyme (unzugängliche) Klasse, die sowohl Bals auch erweitert C, und instanziiert eine einzelne Instanz dieser Klasse mit dem Namen A.

Dieses Mittel Akann an Funktionen übergeben werden, die Objekte vom Typ Boder Coder erwarten B with C.

Zusätzliche Funktionen von object

Es gibt auch einige Besonderheiten von Objekten in Scala. Ich empfehle die offizielle Dokumentation zu lesen .

  • def apply(...) aktiviert die übliche Syntax ohne Methodennamen von A(...)
  • def unapply(...)ermöglicht individuelle Mustervergleich erstellen Extraktoren
  • Wenn das Objekt einer gleichnamigen Klasse beigefügt ist, nimmt es beim Auflösen impliziter Parameter eine besondere Rolle ein
Zikzystar
quelle
38
Außerdem wird Klasse A definiert und alle Methoden in Objekt A als statische Methoden in Klasse A erstellt (für die Schnittstelle mit Java). (Modulo ein Fehler in Scala 2.7, der in Scala 2.8 behoben wurde)
Ken Bloom
2
@ KenBloom wirklich? Ich habe versucht und funktioniert nicht: scala> Commerce res8: Commerce.type = Commerce $ @ 6eb2756 scala> classOf [Commerce] <Konsole>: 23: Fehler: nicht gefunden: Typ Commerce classOf [Commerce] ^ scala> new Commerce < Konsole>: 23: Fehler: nicht gefunden: Typ Commerce new Commerce ^
Hendy Irawan
3
@Hendy: Scala erkennt die CommerceKlasse nicht, die JVM und die Java-Sprache jedoch. (So ​​können Sie object Foo{ def main(args:Seq[String]) }das Programm ausführen und erwarten, dass es ausgeführt wird.)
Ken Bloom
3
Ich denke, Ziggystars Antwort ist präziser, die Klasse ist eine anonyme Klasse, es sei denn, eine entsprechende Klasse mit dem Namen Commerce ist explizit definiert (dann ist das Commerce-Objekt ein Begleitobjekt zur Commerce-Klasse)
Hendy Irawan
3
@ DavidApltauer Ich wette, es gibt genug Feinheiten, die von meiner Antwort nicht abgedeckt werden. Aber diese sind für die meisten Leute, die dies lesen, wahrscheinlich nicht wichtig. Und ich hatte nie Probleme damit, ein Objekt als Instanz eines Merkmals zu übergeben, was nicht bedeutet, dass es nicht existiert. aber es sollte funktionieren.
Ziggystar
249

A classist eine Definition, eine Beschreibung. Es definiert einen Typ in Bezug auf Methoden und Zusammensetzung anderer Typen.

An objectist ein Singleton - eine Instanz einer Klasse, die garantiert eindeutig ist. Für jeden objectCode wird eine anonyme Klasse erstellt, die von allen Klassen erbt, deren objectImplementierung Sie deklariert haben . Diese Klasse kann aus dem Scala-Quellcode nicht gesehen werden - obwohl Sie sie durch Reflexion erreichen können.

Es gibt eine Beziehung zwischen objectund class. Ein Objekt wird als Begleitobjekt einer Klasse bezeichnet, wenn sie denselben Namen haben. In diesem Fall hat jeder Zugriff auf privateSichtbarkeitsmethoden des anderen. Diese Methoden werden jedoch nicht automatisch importiert. Sie müssen sie entweder explizit importieren oder ihnen den Klassen- / Objektnamen voranstellen.

Zum Beispiel:

class X {
  // class X can see private members of object X
  // Prefix to call
  def m(x: Int) = X.f(x)

  // Import and use
  import X._
  def n(x: Int) = f(x)

  private def o = 2
}

object X {
  private def f(x: Int) = x * x

  // object X can see private members of class X
  def g(x: X) = {
    import x._
    x.o * o // fully specified and imported
   }
}
Daniel C. Sobral
quelle
1
Es tut mir leid, Sie zu stören, aber könnten Sie vielleicht auf ein Beispiel verweisen, wie Methoden in das Begleitobjekt importiert oder wie sie vorangestellt werden?
ithkuil
4
@ithkuil Fertig. Entschuldigung für das dumme Beispiel, ich konnte mir kein gutes und kurzes vorstellen.
Daniel C. Sobral
Was ist, wenn ich Klassenmethoden in Object verwenden möchte? Wird das möglich sein? Wenn ich eine Methode einer Klasse habe und sie in Object verwenden möchte, können Sie die Klasse nicht importieren. Schließlich müssen Sie einen Konstruktor erstellen und dann die Methode aufrufen. Wenn Sie also ein Begleitobjekt erstellen, können Sie mithilfe des Imports auf die Methoden von Object zugreifen, nicht jedoch umgekehrt. Kann jemand bitte validieren?
PiyushGoyal
@piyushGoyal Nicht wahr. Angenommen, das Objekt verfügt über eine Methode der Companion-Klasse def f(x: X) = ???, dann können private Methoden aufgerufen werden . xX
Daniel C. Sobral
Hier ist X, das in der Funktion übergeben wurde, eine Instanz der Klasse XI. Wenn ja, dann verwenden Sie schließlich das Objekt x, um die Methode der X-Klasse in der def f aufzurufen. Richtig?
PiyushGoyal
76

Ein Objekt hat genau eine Instanz (Sie können nicht aufrufen new MyObject). Sie können mehrere Instanzen einer Klasse haben.

Das Objekt dient denselben (und einigen zusätzlichen) Zwecken wie die statischen Methoden und Felder in Java.

Thomas Jung
quelle
19

Definiert, wie von vielen erklärt, objecteine Singleton-Instanz. Die eine Sache in den Antworten hier, von der ich glaube, dass sie weggelassen wird, ist, dass sie objectmehreren Zwecken dient.

  • Es kann das Begleitobjekt zu einem class/ sein trait, das statische Methoden oder Convenience-Methoden enthält.

  • Es kann sich ähnlich wie ein Modul verhalten, das verwandte / untergeordnete Typen und Definitionen usw. enthält.

  • Es kann eine Schnittstelle implementieren, indem ein classoder ein oder mehrere traits erweitert werden.

  • Es kann einen Fall von a darstellen sealed trait, der keine Daten enthält. In dieser Hinsicht wird es oft als korrekter angesehen als a case classohne Parameter. Der Sonderfall eines sealed traitmit nur case objectImplementierern ist mehr oder weniger die Scala-Version einer Aufzählung.

  • Es kann als Beweis für eine implicitgesteuerte Logik dienen.

  • Es wird ein Singleton-Typ eingeführt.

Es ist ein sehr mächtiges und allgemeines Konstrukt. Was für Scala-Anfänger sehr verwirrend sein kann, ist, dass dasselbe Konstrukt sehr unterschiedliche Verwendungszwecke haben kann. Und eine objectkann viele dieser verschiedenen Verwendungszwecke gleichzeitig erfüllen, was noch verwirrender sein kann.

acjay
quelle
18

Das Definieren eines Objekts in Scala entspricht dem Definieren einer Klasse in Java, die nur statische Methoden enthält. In Scala kann ein Objekt jedoch eine andere Oberklasse erweitern, Schnittstellen implementieren und so weitergegeben werden, als wäre es eine Instanz einer Klasse. (Es ist also wie bei den statischen Methoden einer Klasse, aber besser).

Ken Bloom
quelle
17

Der formale Unterschied -

  1. Sie können keine Konstruktorparameter für Objekte angeben
  2. Objekt ist kein Typ - Sie können möglicherweise keine Instanz mit einem neuen Operator erstellen. Aber es kann Felder und Methoden haben, eine Oberklasse erweitern und Eigenschaften einmischen.

Der Unterschied in der Nutzung:

  • Scala hat keine statischen Methoden oder Felder. Stattdessen sollten Sie verwenden object. Sie können es mit oder ohne zugehörige Klasse verwenden. Im ersten Fall wird es als Begleitobjekt bezeichnet. Sie müssen:
    1. Verwenden Sie für Klasse und Objekt denselben Namen
    2. Legen Sie sie in dieselbe Quelldatei.
  • Um ein Programm zu erstellen, sollten Sie die Hauptmethode in objectund nicht in verwenden class.

    object Hello {
      def main(args: Array[String]) {
        println("Hello, World!")
      }
    }
  • Sie können es auch verwenden, wenn Sie ein Singleton-Objekt in Java verwenden.

      
        
      

irudyak
quelle
"Sie können keine Konstruktorparameter für Objekte angeben" Objekte haben die Methode apply (...), die ähnlich wie ein Konstruktor funktioniert. Das macht mich ein wenig verwirrt.
Danielle
7

Das Objektschlüsselwort erstellt einen neuen Singleton-Typ, der einer Klasse ähnelt , die nur eine einzige benannte Instanz hat. Wenn Sie mit Java vertraut sind, ähnelt das Deklarieren eines Objekts in Scala dem Erstellen einer neuen Instanz einer anonymen Klasse.

Scala hat keine Entsprechung zum statischen Schlüsselwort von Java , und in Scala wird häufig ein Objekt verwendet, in dem Sie möglicherweise eine Klasse mit statischen Elementen in Java verwenden.


quelle
6

Objekt ist eine Klasse, aber es hat (ist) bereits eine Instanz, so dass Sie nicht aufrufen können new ObjectName. Auf der anderen Seite ist Class nur ein Typ und kann durch Aufrufen eine Instanz sein new ClassName().

Yonggoo Noh
quelle
4

In Scala gibt es kein staticKonzept. Daher erstellt scala ein Singleton-Objekt, um den Einstiegspunkt für Ihre Programmausführung bereitzustellen. Wenn Sie kein Singleton-Objekt erstellen, wird Ihr Code erfolgreich kompiliert, es wird jedoch keine Ausgabe erzeugt. In Singleton Object deklarierte Methoden sind global verfügbar. Ein Singleton-Objekt kann Klassen und Merkmale erweitern.

Beispiel für ein Scala Singleton-Objekt

object Singleton{  
    def main(args:Array[String]){  
        SingletonObject.hello()         // No need to create object.  
    }  
}  


object SingletonObject{  
    def hello(){  
        println("Hello, This is Singleton Object")  
    }  
}  

Ausgabe:

Hello, This is Singleton Object

Wenn Sie in Scala eine Klasse mit demselben Namen wie ein Singleton-Objekt haben, wird sie als Companion-Klasse und das Singleton-Objekt als Companion-Objekt bezeichnet.

Die Companion-Klasse und ihr Companion-Objekt müssen beide in derselben Quelldatei definiert sein.

Beispiel für ein Scala-Begleitobjekt

class ComapanionClass{  
    def hello(){  
        println("Hello, this is Companion Class.")  
    }  
}  
object CompanoinObject{  
    def main(args:Array[String]){  
        new ComapanionClass().hello()  
        println("And this is Companion Object.")  
    }  
}  

Ausgabe:

Hello, this is Companion Class.
And this is Companion Object.

In Scala kann eine Klasse Folgendes enthalten:

1. Datenelement

2. Mitgliedsmethode

3. Konstruktorblock

4. Verschachtelte Klasse

5. Super Klasseninformationen usw.

Sie müssen alle Instanzvariablen in der Klasse initialisieren. Es gibt keinen Standardbereich. Wenn Sie keinen Zugriffsbereich angeben, ist dieser öffentlich. Es muss ein Objekt geben, in dem die Hauptmethode definiert ist. Es bietet den Ausgangspunkt für Ihr Programm. Hier haben wir ein Beispiel für eine Klasse erstellt.

Scala Beispiel Beispiel einer Klasse

class Student{  
    var id:Int = 0;                         // All fields must be initialized  
    var name:String = null;  
}  
object MainObject{  
    def main(args:Array[String]){  
        var s = new Student()               // Creating an object  
        println(s.id+" "+s.name);  
    }  
} 

Es tut mir leid, ich bin zu spät, aber ich hoffe, es wird Ihnen helfen.

Bhaskar Das
quelle
2

Scala-Klasse wie Java-Klasse, aber Scala bietet Ihnen keine Eingabemethode in der Klasse, wie die Hauptmethode in Java. Die Hauptmethode, die dem Objektschlüsselwort zugeordnet ist. Sie können sich das Objektschlüsselwort als das Erstellen eines Singleton-Objekts einer Klasse vorstellen, die implizit definiert ist.

Weitere Informationen Überprüfen Sie dieses Artikelklassen- und Objektschlüsselwort in der Scala-Programmierung

FOD
quelle
2

Das Objekt ähnelt in gewissem Maße der statischen Klasse in Java. Das statische Merkmal bedeutet, dass die statische Klasse beim Einfügen in die JVM kein Objekt erstellen muss. Es kann direkt von ihrem Klassennamen und derselben Instanz (demselben Datenstatus) verwendet werden ) wird überall dort geteilt, wo es verwendet wird.

David
quelle
1

Eine Klasse ist wie jede andere Klasse in anderen Sprachen. Sie definieren Klasse wie jede andere Sprache mit einigen Syntaxunterschieden.

class Person(val name: String)
val me = new Person("My name")

Objekt ist jedoch eine Klasse mit nur einem Objekt. Dies macht es interessant, da damit statische Elemente einer Klasse mithilfe eines Begleitobjekts erstellt werden können . Dieses Begleitobjekt hat Zugriff auf private Mitglieder der Klassendefinition und hat denselben Namen wie die von Ihnen definierte Klasse.

class Person(var name: String) {

  import Person._

  def hi(): String = sayHello(name)
}

object Person {
  private def sayHello(name: String): String = "Hello " + name
}

val me = new Person("My name")
me.hi()

Bemerkenswert ist auch, dass die Objektklasse träge erstellt wird, was ein weiterer wichtiger Punkt ist. Diese werden also nur instanziiert, wenn sie in unserem Code benötigt werden.

Wenn Sie die Verbindungserstellung für JDBC definieren, können Sie sie innerhalb eines Objekts erstellen, um Doppelungen zu vermeiden, wie wir es in Java mit Singleton-Objekten tun.

Piyush Patel
quelle
0

Wenn Sie aus dem Java-Hintergrund kommen, ähnelt das Konzept der Klasse in Scala Java, aber die Klasse in Scala kann keine statischen Elemente enthalten.

Objekte in Scala sind Singleton-Objekte, die Sie mithilfe des Objektnamens in ihr aufrufen. In Scala ist das Objekt ein Schlüsselwort und in Java-Objekt eine Instanz der Klasse

Vivek
quelle