2012-03-15 4 views
70

У меня очень простой вопрос - когда мы должны применять новое ключевое слово при создании объектов в Scala? Это когда мы пытаемся создать экземпляр объектов Java?«новое» ключевое слово в Scala

ответ

112

Используйте new ключевое слово, если вы хотите, чтобы обратиться к собственному конструктору class «s:

class Foo { } 

val f = new Foo 

Omit new если вы имеете в виду apply метода объекта спутника:

class Foo { } 
object Foo { 
    def apply() = new Foo 
} 

// Both of these are legal 
val f = Foo() 
val f2 = new Foo 

Если у вас был создан класс корпуса:

case class Foo() 

Scala тайно создает объект компаньоном для вас, превращая его в этом:

class Foo { } 
object Foo { 
    def apply() = new Foo 
} 

Так что вы можете сделать

f = Foo() 

Наконец, не забывайте, что не существует правила, которое говорит о том, что спутник apply метод должен быть прокси для конструктора:

class Foo { } 
object Foo { 
    def apply() = 7 
} 

// These do different things 
> println(new Foo) 
[email protected] 
> println(Foo()) 
7 

и, так как вы упомянули классы Java: да - Java классы редко ВГА e сопутствующих объектов с методом apply, поэтому вы должны использовать new и фактический конструктор класса .

+0

Java, класс не может иметь объект-компаньон. Он может иметь объект, который может работать как Factory для Java-класса, но этот объект не является его сопутствующим объектом. – sschaef

+0

@ Антоны Поскольку классы Scala компилируются в байт-код Java и могут быть распределены в скомпилированной форме, может ли Scala рассказать о различии между реальным компаньоном Scala и классом с именем Foo $ со статическим членом MODULE $? – Owen

+1

Я думаю, что scalac может отличаться от этого, потому что специфицировано, что объект-компаньон должен быть объявлен в том же файле, что и его класс-компаньон.Поскольку сопутствующее «свойство» существует только в Scala, а не на уровне байткода, скалак должен проверить код Scala, а не Bytecode, чтобы убедиться, что спецификация соблюдена. – sschaef

13

Это когда мы пытаемся создать экземпляр объектов Java?

Совсем нет. Существует два общих случая, когда вы опускаете new в scala. С одноэлементными объектами (которые часто используемыми для хранения статических функций и как своего родом фабрики подобно тому, что вы можете увидеть в Java):

scala> object LonelyGuy { def mood = "sad" } 
defined module LonelyGuy 

scala> LonelyGuy 
res0: LonelyGuy.type = [email protected] 

scala> LonelyGuy.mood 
res4: java.lang.String = sad 

С case classes (на самом деле, под есть класс + объект = companion шаблон, например, имеющий класс и объект с тем же именем):

scala> case class Foo(bar: String) 
defined class Foo 


scala> Foo("baz") 
res2: Foo = Foo(baz) 

так что, когда вы работаете с простыми классами, правила такие же, как и с Java.

scala> class Foo(val bar: String) 
defined class Foo 

scala> new Foo("baz") 
res0: Foo = [email protected] 

// will be a error 
scala> Foo("baz") 
<console>:8: error: not found: value Foo 
     Foo("baz") 

Bonus, есть анонимные классы в Скале, которые могут быть построены следующим образом:

scala> new { val bar = "baz" } 
res2: java.lang.Object{val bar: java.lang.String} = [email protected] 

scala> res2.bar 
res3: java.lang.String = baz 
Смежные вопросы