Differenza tra oggetto e classe in Scala


636

Sto solo esaminando alcuni tutorial di Scala su Internet e ho notato in alcuni esempi un oggetto è dichiarato all'inizio dell'esempio.

Qual'è la differenza tra classe objectin Scala?

Risposte:


580

tl; dr

  • class C definisce una classe, proprio come in Java o C ++.
  • object Ocrea un oggetto singletonO come istanza di una classe anonima; può essere utilizzato per contenere membri statici non associati a istanze di alcune classi.
  • object O extends Trende l'oggetto Oun'istanza di trait T; puoi quindi passare Oovunque, Tè previsto un.
  • se c'è un class C, allora object Cè l' oggetto compagno di classe C; si noti che l'oggetto associato non è automaticamente un'istanza di C.

Vedi anche la documentazione Scala per oggetto e classe .

object come host di membri statici

Molto spesso, è necessario objectdisporre di metodi e valori / variabili che devono essere disponibili senza dover prima creare un'istanza di una classe. Questo uso è strettamente correlato ai staticmembri in Java.

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

È quindi possibile chiamare il metodo sopra utilizzando A.twice(2).

Se twicefossi un membro di una classe A, dovrai prima creare un'istanza:

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

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

Puoi vedere quanto è ridondante, in quanto twicenon richiede dati specifici dell'istanza.

object come un'istanza denominata speciale

Puoi anche usare lo objectstesso come un'istanza speciale di una classe o tratto. Quando lo fai, il tuo oggetto deve estenderne alcuni traitper diventare un'istanza di una sua sottoclasse.

Considera il seguente codice:

object A extends B with C {
  ...
}

Questa dichiarazione dichiara innanzitutto una classe anonima (inaccessibile) che estende sia Be Cche crea un'istanza di una singola istanza di questa classe denominata A.

Questo significa che Apuò essere passato a funzioni in attesa di oggetti di tipo Bo C, o B with C.

Funzionalità aggiuntive di object

Esistono anche alcune caratteristiche speciali degli oggetti in Scala. Consiglio di leggere la documentazione ufficiale .

  • def apply(...) abilita la solita sintassi senza nome del metodo di A(...)
  • def unapply(...)consente di creare estrattori di corrispondenza dei motivi personalizzati
  • se accompagna una classe con lo stesso nome, l'oggetto assume un ruolo speciale nella risoluzione dei parametri impliciti

38
Definirà inoltre la classe A e creerà tutti i metodi nell'oggetto A come metodi statici sulla classe A (per l'interfacciamento con Java). (Modulo a bug in Scala 2.7 risolto in Scala 2.8)
Ken Bloom,

2
@KenBloom davvero? Ho provato e non funziona: scala> Commerce res8: Commerce.type = Commerce $ @ 6eb2756 scala> classOf [Commerce] <console>: 23: errore: non trovato: tipo Commerce classOf [Commerce] ^ scala> new Commerce < console>: 23: errore: non trovato: digitare Commerce new Commerce ^
Hendy Irawan

3
@Hendy: Scala non riconoscerà la Commerceclasse, ma la JVM e il linguaggio Java lo riconosceranno. (È così che puoi fare object Foo{ def main(args:Seq[String]) }e aspettarti che il programma funzioni.)
Ken Bloom,

3
Penso che la risposta di ziggystar sia più precisa, la classe è una classe anonima, a meno che una classe corrispondente denominata Commerce sia esplicitamente definita (quindi l'oggetto Commerce sarà un oggetto associato alla classe Commerce)
Hendy Irawan,

3
@DavidApltauer Scommetto che ci sono abbastanza sottigliezze che non sono coperte dalla mia risposta. Ma quelli probabilmente non contano per la maggior parte delle persone che leggono questo. E non ho mai avuto problemi con il passaggio di un oggetto come istanza di qualche tratto, il che non significa che non esistano; ma dovrebbe funzionare.
ziggystar,

249

A classè una definizione, una descrizione. Definisce un tipo in termini di metodi e composizione di altri tipi.

An objectè un singleton - un'istanza di una classe che è garantita per essere unica. Per ogni objectcodice, viene creata una classe anonima, che eredita da qualunque classe tu abbia dichiarato objectdi implementare. Questa classe non può essere vista dal codice sorgente di Scala, anche se puoi ottenerla attraverso la riflessione.

C'è una relazione tra objecte class. Si dice che un oggetto sia l'oggetto compagno di una classe se condividono lo stesso nome. Quando ciò accade, ognuno ha accesso a metodi di privatevisibilità nell'altro. Tuttavia, questi metodi non vengono importati automaticamente. Devi importarli in modo esplicito o aggiungerli come prefisso con il nome classe / oggetto.

Per esempio:

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
   }
}

1
Mi dispiace disturbarti, ma potresti forse indicare un esempio su come importare metodi nell'oggetto associato o come prefissarli?
ithkuil,

4
@ithkuil Done. Mi dispiace per l'esempio sciocco, non riuscivo a pensare a uno buono e breve.
Daniel C. Sobral,

Cosa succede se desidero utilizzare il metodo di classe in Object? Sarebbe possibile? Se ho un metodo di una classe e voglio usarlo in Object, quindi se provi a importare la classe, non sarai in grado di farlo. Alla fine devi creare un costruttore e chiamare il metodo quindi. Quindi, creando un oggetto associato, è possibile accedere ai metodi di Object usando import ma non viceversa. Qualcuno può convalidare per favore?
piyush Goyal

@piyushGoyal Non è vero. Supponiamo che l'oggetto abbia un metodo def f(x: X) = ???, quindi sarebbe in grado di chiamare metodi privati x, della classe associata X.
Daniel C. Sobral,

Qui X passato nella funzione è un'istanza di classe XI indovina? Se sì, allora alla fine stai usando l'oggetto x per chiamare il metodo di classe X nella def f. Giusto?
piyush Goyal

76

Un oggetto ha esattamente un esempio (non si può chiamare new MyObject). Puoi avere più istanze di una classe.

L'oggetto ha gli stessi (e alcuni scopi aggiuntivi) dei metodi e dei campi statici in Java.


19

Come è stato spiegato da molti, objectdefinisce un'istanza singleton. L'unica cosa nelle risposte qui che ritengo sia esclusa è che ha objectdiversi scopi.

  • Può essere l'oggetto associato a class/ trait, contenente quelli che potrebbero essere considerati metodi statici o metodi di convenienza.

  • Può agire in modo simile a un modulo, contenente tipi e definizioni correlati / sussidiari, ecc

  • Può implementare un'interfaccia estendendo classuno o più o più traitsecondi.

  • Può rappresentare un caso di un sealed traitche non contiene dati. A questo proposito, è spesso considerato più corretto di un case classsenza parametri. Il caso speciale di un sealed traitcon solo case objectimplementatori è più o meno la versione Scala di un enum.

  • Può fungere da prova per la implicitlogica guidata.

  • Presenta un tipo singleton.

È un costrutto molto potente e generale. Ciò che può essere molto confuso per i principianti di Scala è che lo stesso costrutto può avere usi molto diversi. E un objectpuò servire molti di questi diversi usi contemporaneamente, il che può essere ancora più confuso.


18

Definire un oggetto in Scala è come definire una classe in Java che ha solo metodi statici. Tuttavia, in Scala un oggetto può estendere un'altra superclasse, implementare interfacce ed essere passato come se fosse un'istanza di una classe. (Quindi è come i metodi statici su una classe ma meglio).


17

La differenza formale -

  1. non è possibile fornire parametri del costruttore per gli oggetti
  2. L'oggetto non è un tipo: non è possibile creare un'istanza con un nuovo operatore. Ma può avere campi, metodi, estendere una superclasse e mescolare tratti.

La differenza nell'uso:

  • Scala non ha metodi o campi statici. Invece dovresti usare object. Puoi usarlo con o senza classe correlata. Nel primo caso si chiama oggetto associato. Devi:
    1. usa lo stesso nome sia per classe che per oggetto
    2. metterli nello stesso file di origine.
  • Per creare un programma devi usare il metodo principale object, non in class.

    object Hello {
      def main(args: Array[String]) {
        println("Hello, World!")
      }
    }
  • Puoi anche usarlo mentre usi singleton in java.

      
        
      


"non è possibile fornire parametri del costruttore per gli oggetti" Gli oggetti hanno il metodo apply (...), che funziona in modo molto simile a un costruttore. Questo mi lascia un po 'confuso.
Danielle

7

La parola chiave object crea un nuovo tipo singleton, che è come una classe che ha solo una singola istanza denominata. Se hai familiarità con Java, dichiarare un oggetto in Scala è molto simile alla creazione di una nuova istanza di una classe anonima.

Scala non ha equivalenti alla parola chiave statica di Java e un oggetto è spesso usato in Scala dove potresti usare una classe con membri statici in Java.


6

L'oggetto è una classe ma ha già (è) un'istanza, quindi non puoi chiamarla new ObjectName. D'altra parte, Class è solo il tipo e può essere un'istanza chiamando new ClassName().


4

In scala, non esiste un staticconcetto. Quindi scala crea un oggetto singleton per fornire il punto di ingresso per l'esecuzione del programma. Se non si crea un oggetto singleton, il codice verrà compilato correttamente ma non produrrà alcun output. I metodi dichiarati all'interno di Singleton Object sono accessibili a livello globale. Un oggetto singleton può estendere classi e tratti.

Esempio di oggetto Scala Singleton

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


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

Produzione:

Hello, This is Singleton Object

In scala, quando hai una classe con lo stesso nome dell'oggetto singleton, si chiama classe compagno e l'oggetto singleton si chiama oggetto compagno.

La classe companion e il suo oggetto companion devono essere entrambi definiti nello stesso file di origine.

Esempio di oggetto Scala Companion

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.")  
    }  
}  

Produzione:

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

In scala, una classe può contenere:

1. Membro dei dati

2. Metodo membro

3. Blocco costruttore

4. Classe nidificata

5. Informazioni super class ecc.

È necessario inizializzare tutte le variabili di istanza nella classe. Non esiste un ambito predefinito. Se non si specifica l'ambito di accesso, è pubblico. Ci deve essere un oggetto in cui è definito il metodo principale. Fornisce il punto di partenza per il tuo programma. Qui, abbiamo creato un esempio di classe.

Scala Esempio di classe

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);  
    }  
} 

Mi dispiace, sono troppo tardi, ma spero che ti possa aiutare.


2

La classe Scala è uguale alla classe Java ma scala non fornisce alcun metodo di immissione in classe, come il metodo principale in Java. Il metodo principale associato alla parola chiave object. Puoi pensare alla parola chiave object come alla creazione di un oggetto singleton di una classe definita in modo implicito.

ulteriori informazioni consulta questa classe di articoli e la parola chiave object nella programmazione scala


2

L'oggetto è simile alla classe statica in Java in qualche modo, la caratteristica statica significa che la classe statica non ha bisogno di creare un oggetto quando si inserisce nella JVM, può essere utilizzata direttamente dal nome della sua classe e dalla stessa istanza (stesso stato dei dati ) è condiviso ovunque sia utilizzato.


1

Una classe è come qualsiasi altra classe in altre lingue. Definisci la classe come qualsiasi altra lingua con qualche differenza di sintassi.

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

Tuttavia, object è una classe con un solo oggetto. Ciò lo rende interessante in quanto può essere utilizzato per creare membri statici di una classe utilizzando l' oggetto associato . Questo oggetto associato ha accesso ai membri privati ​​della definizione della classe e ha lo stesso nome della classe che stai definendo.

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()

Inoltre, il punto degno di nota è che la classe di oggetti è pigramente creata, il che è un altro punto importante. Quindi, questi non sono istanziati a meno che non siano necessari nel nostro codice.

Se stai definendo la creazione di connessioni per JDBC, puoi crearle all'interno dell'oggetto per evitare la duplicazione, proprio come facciamo in Java con oggetti singleton.


0

Se provieni da Java background, il concetto di classe in scala è in qualche modo simile a Java, ma la classe in scala non può contenere membri statici.

Gli oggetti in scala sono di tipo singleton che chiami metodi al suo interno usando il nome dell'oggetto, in oggetto scala è una parola chiave e in java è un'istanza di classe

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.