Diferencia entre objeto y clase en Scala

636

Solo estoy revisando algunos tutoriales de Scala en Internet y he notado en algunos ejemplos que se declara un objeto al comienzo del ejemplo.

¿Cuál es la diferencia entre classy objecten Scala?

Steve
fuente

Respuestas:

580

tl; dr

  • class C define una clase, tal como en Java o C ++.
  • object Ocrea un objeto singletonO como instancia de alguna clase anónima; se puede usar para mantener miembros estáticos que no están asociados con instancias de alguna clase.
  • object O extends Tconvierte el objeto en Ouna instancia de trait T; luego puede pasar a Ocualquier lugar, Tse espera a.
  • si hay un class C, entonces object Ces el objeto compañero de la clase C; tenga en cuenta que el objeto complementario no es automáticamente una instancia de C.

Consulte también la documentación de Scala para el objeto y la clase .

object como anfitrión de miembros estáticos

En la mayoría de los casos, necesita una objectpara contener métodos y valores / variables que estarán disponibles sin tener que instanciar primero una instancia de alguna clase. Este uso está estrechamente relacionado con los staticmiembros en Java.

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

Luego puede llamar al método anterior usando A.twice(2).

Si twicefuera miembro de alguna clase A, primero necesitaría hacer una instancia:

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

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

Puede ver cuán redundante es esto, ya twiceque no requiere ningún dato específico de la instancia.

object como una instancia especial con nombre

También puede usar el objectpropio como alguna instancia especial de una clase o rasgo. Cuando haces esto, tu objeto necesita extenderse un poco traitpara convertirse en una instancia de una subclase de él.

Considere el siguiente código:

object A extends B with C {
  ...
}

Esta declaración declara por primera vez una clase anónima (inaccesibles) que se extiende a ambos By C, y crea la instancia de una única instancia de esta clase llamada A.

Esto significa que Apuede pasarse a funciones que esperan objetos de tipo Bo C, o B with C.

Características adicionales de object

También existen algunas características especiales de los objetos en Scala. Recomiendo leer la documentación oficial .

  • def apply(...) habilita la sintaxis sin nombre del método habitual de A(...)
  • def unapply(...)permite crear extractores de coincidencia de patrones personalizados
  • si acompaña a una clase del mismo nombre, el objeto asume un papel especial al resolver parámetros implícitos
ziggystar
fuente
38
También definirá la clase A y creará todos los métodos en el objeto A como métodos estáticos en la clase A (para interactuar con Java). (Módulo un error en Scala 2.7 que se ha solucionado en Scala 2.8)
Ken Bloom
2
@KenBloom realmente? Intenté y no funciona: scala> Commerce res8: Commerce.type = Commerce $ @ 6eb2756 scala> classOf [Commerce] <consola>: 23: error: no encontrado: escriba Commerce classOf [Commerce] ^ scala> new Commerce < consola>: 23: error: no encontrado: escriba Commerce new Commerce ^
Hendy Irawan
3
@Hendy: Scala no reconocerá la Commerceclase, pero la JVM y el lenguaje Java sí. (Así es como puedes hacer object Foo{ def main(args:Seq[String]) }y esperar que el programa se ejecute.)
Ken Bloom
3
Creo que la respuesta de ziggystar es más precisa, la clase es una clase anónima, a menos que se defina explícitamente una clase correspondiente llamada Comercio (entonces el objeto Comercio será un objeto complementario a la clase Comercio)
Hendy Irawan
3
@DavidApltauer Apuesto a que hay suficientes sutilezas que no están cubiertas por mi respuesta. Pero eso probablemente no sea importante para la mayoría de las personas que leen esto. Y nunca tuve problemas para pasar un objeto como una instancia de algún rasgo, lo que no significa que no existan; Pero debería funcionar.
ziggystar
249

A classes una definición, una descripción. Define un tipo en términos de métodos y composición de otros tipos.

Un objectes un singleton, una instancia de una clase que se garantiza que es única. Para cada parte objectdel código, se crea una clase anónima, que hereda de las clases que declaró objectimplementar. Esta clase no se puede ver desde el código fuente de Scala, aunque se puede obtener a través de la reflexión.

Hay una relación entre objecty class. Se dice que un objeto es el objeto compañero de una clase si comparten el mismo nombre. Cuando esto sucede, cada uno tiene acceso a métodos de privatevisibilidad en el otro. Sin embargo, estos métodos no se importan automáticamente. Tiene que importarlos explícitamente o prefijarlos con el nombre de clase / objeto.

Por ejemplo:

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
fuente
1
Lamento molestarlo, pero ¿podría quizás señalar un ejemplo sobre cómo importar métodos en el objeto complementario o cómo prefijarlos?
ithkuil
44
@ithkuil Hecho. Perdón por el ejemplo tonto, no podría pensar en uno bueno y corto.
Daniel C. Sobral
¿Qué pasa si quiero usar métodos de clase en Object? ¿Sería eso posible? Si tengo un método de una clase y quiero usarlo en Object, entonces si intentas importar la clase, no podrás hacerlo. Finalmente, debe hacer un constructor y llamar al método entonces. Por lo tanto, al hacer un objeto complementario, puede acceder a los métodos de Objeto mediante la importación, pero no al revés. ¿Alguien puede validar?
piyushGoyal
@piyushGoyal No es cierto. Digamos que el objeto tiene un método def f(x: X) = ???, entonces podría llamar a métodos privados x, de la clase compañera X.
Daniel C. Sobral
Aquí X pasado en la función es instancia de clase X, ¿supongo? En caso afirmativo, finalmente está utilizando el objeto x para llamar al método de la clase X en la definición f .. ¿Correcto?
piyushGoyal
76

Un objeto tiene exactamente una instancia (no se puede llamar new MyObject). Puede tener varias instancias de una clase.

El objeto cumple los mismos propósitos (y algunos más) que los métodos y campos estáticos en Java.

Thomas Jung
fuente
19

Como muchos han explicado, objectdefine una instancia singleton. Lo único en las respuestas aquí que creo que se omite es que objecttiene varios propósitos.

  • Puede ser el objeto complementario de un class/ trait, que contiene lo que podría considerarse métodos estáticos o métodos de conveniencia.

  • Puede actuar como un módulo, que contiene tipos y definiciones relacionados / subsidiarios, etc.

  • Puede implementar una interfaz extendiendo classuno o más traits.

  • Puede representar un caso de un sealed traitque no contiene datos. A este respecto, a menudo se considera más correcto que case classa sin parámetros. El caso especial de un sealed traitcon solo case objectimplementadores es más o menos la versión Scala de una enumeración.

  • Puede actuar como evidencia de la implicitlógica impulsada.

  • Introduce un tipo singleton.

Es una construcción muy poderosa y general. Lo que puede ser muy confuso para los principiantes de Scala es que la misma construcción puede tener usos muy diferentes. Y objectpuede servir muchos de estos diferentes usos a la vez, lo que puede ser aún más confuso.

acjay
fuente
18

Definir un objeto en Scala es como definir una clase en Java que solo tiene métodos estáticos. Sin embargo, en Scala un objeto puede extender otra superclase, implementar interfaces y pasarlo como si fuera una instancia de una clase. (Entonces es como los métodos estáticos en una clase pero mejor).

Ken Bloom
fuente
17

La diferencia formal

  1. no puede proporcionar parámetros de constructor para objetos
  2. El objeto no es un tipo: no puede crear una instancia con un nuevo operador. Pero puede tener campos, métodos, extender una superclase y mezclar rasgos.

La diferencia en el uso:

  • Scala no tiene métodos o campos estáticos. En su lugar deberías usar object. Puede usarlo con o sin clase relacionada. En el primer caso se llama objeto complementario. Tienes que:
    1. use el mismo nombre para la clase y el objeto
    2. póngalos en el mismo archivo fuente.
  • Para crear un programa, debe usar el método principal en object, no en class.

    object Hello {
      def main(args: Array[String]) {
        println("Hello, World!")
      }
    }
  • También puede usarlo al usar un objeto singleton en java.

      
        
      

irudyak
fuente
"no puede proporcionar parámetros de constructor para objetos" Los objetos tienen el método apply (...), que funciona de manera muy similar a un constructor. Esto me deja un poco confundido.
Danielle
7

La palabra clave object crea un nuevo tipo singleton, que es como una clase que solo tiene una única instancia con nombre. Si está familiarizado con Java, declarar un objeto en Scala es muy parecido a crear una nueva instancia de una clase anónima.

Scala no tiene equivalente a la palabra clave estática de Java , y un objeto a menudo se usa en Scala, donde puede usar una clase con miembros estáticos en Java.


fuente
6

Object es una clase pero ya tiene (es) una instancia, por lo que no puede llamar new ObjectName. Por otro lado, Class es solo tipo y puede ser una instancia llamando new ClassName().

Yonggoo Noh
fuente
4

En scala, no hay staticconcepto. Entonces scala crea un objeto singleton para proporcionar un punto de entrada para la ejecución de su programa. Si no crea un objeto singleton, su código se compilará correctamente pero no generará ningún resultado. Los métodos declarados dentro de Singleton Object son accesibles globalmente. Un objeto singleton puede extender clases y rasgos.

Ejemplo de objeto 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")  
    }  
}  

Salida:

Hello, This is Singleton Object

En scala, cuando tiene una clase con el mismo nombre que el objeto singleton, se llama clase acompañante y el objeto singleton se llama objeto acompañante.

La clase complementaria y su objeto complementario deben definirse en el mismo archivo fuente.

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

Salida:

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

En scala, una clase puede contener:

1. Miembro de datos

2. Método del miembro

3. Bloque constructor

4. Clase anidada

5. Información de super clase, etc.

Debe inicializar todas las variables de instancia en la clase. No hay alcance predeterminado. Si no especifica el alcance de acceso, es público. Debe haber un objeto en el que se defina el método principal. Proporciona un punto de partida para su programa. Aquí, hemos creado un ejemplo de clase.

Ejemplo de clase Scala de clase

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

Lo siento, es demasiado tarde, pero espero que te ayude.

Bhaskar Das
fuente
2

La clase Scala es igual a la clase Java, pero scala no le ofrece ningún método de entrada en clase, como el método principal en Java. El método principal asociado con la palabra clave objeto. Puede pensar en la palabra clave object como la creación de un objeto singleton de una clase que se define implícitamente.

Para obtener más información, consulte esta clase de artículo y la palabra clave de objeto en la programación de Scala

FOD
fuente
2

El objeto es similar a la clase estática en Java hasta cierto punto, la característica estática significa que la clase estática no necesita crear un objeto cuando se coloca en la JVM, puede usarse directamente por su nombre de clase y la misma instancia (mismo estado de datos ) se comparte donde sea que se use.

David
fuente
1

Una clase es como cualquier otra clase en otros idiomas. Define la clase como cualquier otro idioma con alguna diferencia de sintaxis.

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

Sin embargo, object es una clase con un solo objeto solamente. Esto lo hace interesante ya que se puede usar para crear miembros estáticos de una clase usando un objeto complementario . Este objeto complementario tiene acceso a miembros privados de la definición de clase y tiene el mismo nombre que la clase que está definiendo.

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

Además, un punto notable es que la clase de objeto se crea perezosamente, que es otro punto importante. Por lo tanto, estos no se instancian a menos que sean necesarios en nuestro código.

Si está definiendo la creación de conexión para JDBC, puede crearlos dentro del objeto para evitar la duplicación al igual que lo hacemos en Java con objetos singleton.

Piyush Patel
fuente
0

Si viene de Java, el concepto de clase en scala es similar a Java, pero la clase en scala no puede contener miembros estáticos.

Los objetos en scala son de tipo singleton al que llamas métodos dentro de él usando el nombre del objeto, en scala el objeto es una palabra clave y en java el objeto es una instancia de clase

Vivek
fuente