Diferença entre objeto e classe no Scala

636

Estou analisando alguns tutoriais do Scala na Internet e notei em alguns exemplos que um objeto é declarado no início do exemplo.

Qual é a diferença entre classe objectno Scala?

Steve
fonte

Respostas:

580

tl; dr

  • class C define uma classe, assim como em Java ou C ++.
  • object Ocria um objeto singletonO como instância de alguma classe anônima; pode ser usado para armazenar membros estáticos que não estão associados a instâncias de alguma classe.
  • object O extends Ttorna o objeto Ouma instância de trait T; então você pode passar para Oqualquer lugar, umT é esperado.
  • se houver class C, então object Cé o objeto complementar da classe C; observe que o objeto complementar não é automaticamente uma instância de C.

Consulte também a documentação do Scala para objeto e classe .

object como host de membros estáticos

Na maioria das vezes, você precisa objectmanter métodos e valores / variáveis ​​que devem estar disponíveis sem precisar instanciar uma instância de alguma classe. Esse uso está intimamente relacionado aos staticmembros em Java.

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

Você pode chamar o método acima usando A.twice(2).

Se você twicefosse membro de alguma classe A, seria necessário primeiro criar uma instância:

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

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

Você pode ver como isso é redundante, pois twicenão requer nenhum dado específico da instância.

object como uma instância nomeada especial

Você também pode usar o objectpróprio como uma instância especial de uma classe ou característica. Quando você faz isso, seu objeto precisa estender um pouco traitpara se tornar uma instância de uma subclasse dele.

Considere o seguinte código:

object A extends B with C {
  ...
}

Esta declaração primeiro declara uma classe anônima (inacessível) que se estende tanto Be C, e instancia uma única instância desta classe chamada A.

Isso significa que Apode ser passado para funções que esperam objetos do tipo Bou C, ou B with C.

Recursos adicionais de object

Também existem alguns recursos especiais de objetos no Scala. Eu recomendo ler a documentação oficial .

  • def apply(...) ativa a sintaxe usual do método sem nome de A(...)
  • def unapply(...)permite criar extratores de correspondência de padrão personalizados
  • se acompanha uma classe de mesmo nome, o objeto assume uma função especial ao resolver parâmetros implícitos
ziggystar
fonte
38
Ele também definirá a classe A e criará todos os métodos no objeto A como métodos estáticos na classe A (para interface com Java). (Modulo um bug no Scala 2.7 que foi corrigido no Scala 2.8)
Ken Bloom
2
@KenBloom realmente? Tentei e não funciona: scala> Commerce res8: Commerce.type = Commerce $ @ 6eb2756 scala> classOf [Commerce] <console>: 23: erro: não encontrado: tipo Commerce classOf [Commerce] ^ scala> new Commerce < console>: 23: erro: não encontrado: digite Commerce novo Commerce ^
Hendy Irawan 7/11
3
@ Hendy: Scala não reconhecerá a Commerceclasse, mas a JVM e a linguagem Java reconhecerão . (É assim que você pode fazer object Foo{ def main(args:Seq[String]) }e esperar que o programa seja executado.)
Ken Bloom
3
Eu acho que a resposta de ziggystar é mais preciso, a classe é uma classe anônima, a menos que uma classe correspondente chamado Commerce é explicitamente definido (então Comércio objeto será um objeto companheiro para a classe Commerce)
Hendy Irawan
3
@DavidApltauer Aposto que existem sutilezas suficientes que não são cobertas pela minha resposta. Mas isso provavelmente não importa para a maioria das pessoas que lê isso. E nunca tive problemas em passar um objeto como instância de alguma característica, o que não significa que eles não existam; mas deve funcionar.
Ziggystar 29/11
249

A classé uma definição, uma descrição. Ele define um tipo em termos de métodos e composição de outros tipos.

An objecté um singleton - uma instância de uma classe que é garantida como única. Para cada objectcódigo, é criada uma classe anônima, que herda de quaisquer classes que você declarou objectimplementar. Essa classe não pode ser vista no código-fonte do Scala - embora você possa entender através da reflexão.

Existe uma relação entre objecte class. Diz-se que um objeto é o objeto complementar de uma classe se eles compartilharem o mesmo nome. Quando isso acontece, cada um tem acesso a métodos de privatevisibilidade no outro. Esses métodos não são importados automaticamente, no entanto. Você precisa importá-los explicitamente ou prefixá-los com o nome da classe / objeto.

Por exemplo:

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
fonte
1
Desculpe incomodá-lo, mas talvez você possa apontar para um exemplo sobre como importar métodos para o objeto complementar ou como prefixá-los?
Ithkuil
4
@ithkuil Concluído. Desculpe pelo exemplo bobo, eu não conseguia pensar em um bom e curto.
Daniel C. Sobral
E se eu quiser usar os métodos de classe no Object? Isso seria possível? Se eu tiver um método de classe e quiser usá-lo em Object, se você tentar importar a classe, não poderá. Eventualmente, você precisa criar um construtor e chamar o método então. Portanto, criando um objeto complementar, você pode acessar os métodos de Objeto usando a importação, mas não vice-versa. Alguém pode validar?
piyushGoyal
@piyushGoyal Não é verdade. Digamos que o objeto tenha um método e def f(x: X) = ???, em seguida, ele poderá chamar métodos particulares x, da classe complementar X.
Daniel C. Sobral
Aqui o X passado na função é instância da classe XI, acho? Se sim, eventualmente você está usando o objeto x para chamar o método da classe X no def .. Certo?
piyushGoyal
76

Um objeto tem exatamente uma instância (você não pode chamar new MyObject). Você pode ter várias instâncias de uma classe.

O objeto serve aos mesmos propósitos (e alguns adicionais) dos métodos e campos estáticos em Java.

Thomas Jung
fonte
19

Como já foi explicado por muitos, objectdefine uma instância singleton. A única coisa nas respostas aqui que acredito ser deixada de fora é que objectserve a vários propósitos.

  • Pode ser o objeto complementar de um class/ trait, contendo o que pode ser considerado métodos estáticos ou métodos de conveniência.

  • Pode agir como um módulo, contendo definições e tipos relacionados / subsidiários, etc.

  • Ele pode implementar uma interface estendendo um classou um ou mais traits.

  • Pode representar um caso de um sealed traitque não contém dados. A esse respeito, geralmente é considerado mais correto que um case classsem parâmetros. O caso especial de um sealed traitcom apenas case objectimplementadores é mais ou menos a versão Scala de um enum.

  • Pode atuar como evidência para a implicitlógica orientada.

  • Introduz um tipo singleton.

É uma construção muito poderosa e geral. O que pode ser muito confuso para os iniciantes do Scala é que o mesmo construto pode ter usos muito diferentes. E objectpode servir para muitos desses diferentes usos ao mesmo tempo, o que pode ser ainda mais confuso.

acjay
fonte
18

Definir um objeto no Scala é como definir uma classe em Java que possui apenas métodos estáticos. No entanto, no Scala, um objeto pode estender outra superclasse, implementar interfaces e ser transmitido como se fosse uma instância de uma classe. (Portanto, é como os métodos estáticos em uma classe, mas melhor).

Ken Bloom
fonte
17

A diferença formal -

  1. você não pode fornecer parâmetros de construtor para objetos
  2. O objeto não é um tipo - você não pode criar uma instância com o novo operador. Mas pode ter campos, métodos, estender uma superclasse e misturar características.

A diferença no uso:

  • O Scala não possui métodos ou campos estáticos. Em vez disso, você deve usar object. Você pode usá-lo com ou sem classe relacionada. No primeiro caso, é chamado de objeto complementar. Voce tem que:
    1. use o mesmo nome para classe e objeto
    2. coloque-os no mesmo arquivo de origem.
  • Para criar um programa, você deve usar o método principal em object, não em class.

    object Hello {
      def main(args: Array[String]) {
        println("Hello, World!")
      }
    }
  • Você também pode usá-lo como usa o objeto singleton em java.

      
        
      

irudyak
fonte
"você não pode fornecer parâmetros de construtor para objetos" Os objetos têm o método apply (...), que funciona muito como um construtor. Isso me deixa um pouco confuso.
Danielle
7

A palavra-chave object cria um novo tipo de singleton, que é como uma classe que possui apenas uma única instância nomeada. Se você estiver familiarizado com Java, declarando um objeto no Scala é como criar uma nova instância de uma classe anônima.

Scala não tem equivalente à palavra-chave estática do Java , e um objeto é frequentemente usado no Scala onde você pode usar uma classe com membros estáticos em Java.


fonte
6

O objeto é uma classe, mas já possui (é) uma instância, portanto você não pode chamar new ObjectName. Por outro lado, Class é apenas um tipo e pode ser uma instância chamando new ClassName().

Yonggoo Noh
fonte
4

Na Scala, não há staticconceito. Portanto, o scala cria um objeto singleton para fornecer um ponto de entrada para a execução do seu programa. Se você não criar um objeto singleton, seu código será compilado com êxito, mas não produzirá nenhuma saída. Os métodos declarados dentro do Singleton Object são acessíveis globalmente. Um objeto singleton pode estender classes e características.

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

Resultado:

Hello, This is Singleton Object

No scala, quando você tem uma classe com o mesmo nome que o objeto singleton, ela é chamada de classe complementar e o objeto singleton é chamado de objeto complementar.

A classe complementar e seu objeto complementar devem ser definidos no mesmo arquivo de origem.

Exemplo de objeto complementar Scala

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

Resultado:

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

No scala, uma classe pode conter:

1. Membro dos dados

2. Método membro

3. Bloco Construtor

4. Classe aninhada

5. Informações de classe super etc.

Você deve inicializar todas as variáveis ​​de instância na classe. Não há escopo padrão. Se você não especificar o escopo de acesso, é público. Deve haver um objeto no qual o método principal esteja definido. Ele fornece o ponto de partida para o seu programa. Aqui, criamos um exemplo de classe.

Exemplo de Classe Scala de 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);  
    }  
} 

Sinto muito, estou muito atrasado, mas espero que ajude você.

Bhaskar Das
fonte
2

A classe Scala é igual à Java Class, mas o scala não fornece nenhum método de entrada na classe, como o método principal em java. O principal método associado à palavra-chave do objeto. Você pode pensar na palavra-chave do objeto como a criação de um objeto singleton de uma classe definida implicitamente.

Para obter mais informações, consulte este artigo classe e objeto de palavra-chave na programação scala

FOD
fonte
2

O objeto é semelhante à classe estática em Java, até certo ponto, a característica estática significa que a classe estática não precisa criar um objeto ao colocar na JVM, pode ser usada diretamente por seu nome de classe e pela mesma instância (mesmo estado de dados ) é compartilhado onde quer que seja usado.

David
fonte
1

Uma classe é como qualquer outra classe em outros idiomas. Você define classe como qualquer outro idioma com alguma diferença de sintaxe.

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

No entanto, objeto é uma classe apenas com um único objeto. Isso o torna interessante, pois pode ser usado para criar membros estáticos de uma classe usando o objeto complementar . Esse objeto complementar tem acesso a membros particulares da definição de classe e tem o mesmo nome da classe que você está definindo.

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

Além disso, um ponto digno de nota é que a classe de objetos é criada preguiçosamente, o que é outro ponto importante. Portanto, eles não são instanciados, a menos que sejam necessários em nosso código.

Se você estiver definindo a criação da conexão para JDBC, poderá criá-los dentro do objeto para evitar duplicação, como fazemos em Java com objetos singleton.

Piyush Patel
fonte
0

Se você é proveniente de Java, o conceito de classe no scala é semelhante ao Java, mas a classe no scala não pode conter membros estáticos.

Objetos no scala são do tipo singleton, você chama métodos dentro dele usando o nome do objeto, no objeto scala é uma palavra-chave e no objeto java é uma instância da classe

Vivek
fonte