Scala'da "yeni" anahtar kelime


96

Çok basit bir sorum var - Scala'da nesneler oluştururken yeni anahtar kelimeyi ne zaman uygulamalıyız? Sadece Java nesnelerini başlatmaya çalıştığımızda mı?

Yanıtlar:


146

Kendi kurucusuna newbaşvurmak istediğinizde anahtar kelimeyi kullanın class:

class Foo { }

val f = new Foo

newTamamlayıcı nesnenin applyyöntemine atıfta bulunuyorsanız atlayın :

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

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

Bir vaka sınıfı yaptıysanız:

case class Foo()

Scala sizin için gizlice bir eş nesne yaratır ve onu şuna dönüştürür:

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

Böylece yapabilirsin

f = Foo()

Son olarak, tamamlayıcı apply yöntemin kurucu için bir vekil olması gerektiğini söyleyen bir kural olmadığını unutmayın :

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

// These do different things
> println(new Foo)
test@5c79cc94
> println(Foo())
7

Ve Java sınıflarından bahsettiğinizden beri: evet - Java sınıfları nadiren bir applyyöntemle eşlik eden nesneler içerir , bu nedenle newve gerçek sınıfın yapıcısını kullanmalısınız.


1
Bir Java sınıfının hiçbir zaman eşlik eden bir nesnesi olamaz. Java sınıfı için Fabrika olarak çalışabilen bir nesneye sahip olabilir - ancak bu nesne ona eşlik eden nesne değildir.
kiritsuku

@Antoras Scala sınıfları Java bayt koduna derlendiğinden ve derlenmiş biçimde dağıtılabildiğinden, Scala gerçek bir Scala arkadaşı ile statik MODULE $ üyeli Foo $ adlı bir sınıf arasındaki farkı söyleyebilir mi?
Owen

1
Scalac'ın bundan farklı olabileceğini düşünüyorum çünkü bir tamamlayıcı nesnenin, eşlik eden sınıfla aynı dosyada bildirilmesi gerektiği belirtiliyor. Tamamlayıcı "özelliği" yalnızca Scala'da bulunduğundan ve Bytecode düzeyinde scalac'ta olmadığından, spesifikasyona uyulduğundan emin olmak için Bytecode'u değil Scala kodunu kontrol etmelidir.
kiritsuku

1
Scala'da yeni anahtar sözcüğü KULLANMAYAN Java sınıfı örnekleri var mı?
Bober02

Ayrıca, tamamlayıcı nesnedeki yöntemler, sınıfta da statik yöntemler aracılığıyla erişilebilir hale getirilecek ve bu, daha sonra bir "tamamlayıcı" tanımladığınız java sınıflarında asla gerçekleşmeyecektir.
drexin

16

Sadece java nesnelerini somutlaştırmaya çalıştığımızda mı?

Bir şey değil. Ölçeklendirmeyi ihmal ettiğinizde iki genel durum vardır new. Tekil nesnelerle (genellikle statik işlevleri depolamak için ve java'da gördüklerinize benzer bir tür fabrika olarak kullanılır):

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

scala> LonelyGuy
res0: LonelyGuy.type = LonelyGuy$@3449a8

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

Bir vaka sınıfları ile (aslında, altında sınıf + nesne = tamamlayıcı model vardır, örneğin aynı ada sahip sınıf ve nesneye sahip olmak):

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


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

Yani basit bir sınıfla çalıştığınızda, kurallar Java ile aynıdır.

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

scala> new Foo("baz")
res0: Foo = Foo@2ad6a0

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

Bonus, şu şekilde inşa edilebilen ölçeklendirmede anonim sınıflar vardır:

scala> new { val bar = "baz" }
res2: java.lang.Object{val bar: java.lang.String} = $anon$1@10ee5b8

scala> res2.bar
res3: java.lang.String = baz

1
İyi misin dostum?
Jacob B

0

Sadece Java nesnelerini başlatmaya çalıştığımızda mı?

Dotty'ye dayanan Scala 3 (sekiz yıl sonra, 2020'nin ortasında piyasaya sürülmelidir) : asla.

Scala 3, bu ileti dizisindekinew gibi " " bırakacak

Oluşturan uygulamalar, uygulama yöntemi uygulanmamış olsa bile, bir sınıfın örneklerini oluşturmak için basit işlev çağrısı sözdiziminin kullanılmasına izin verir.

Misal:

class StringBuilder(s: String) {
   def this() = this(s)
}

StringBuilder("abc")  // same as new StringBuilder("abc")
StringBuilder()       // same as new StringBuilder()

Oluşturan uygulamalar, şimdiye kadar yalnızca vaka sınıfları için sağlanan bir işlevi genelleştirir, ancak bunun nasıl elde edildiği mekanizma biraz farklıdır.
Otomatik olarak oluşturulan bir uygulama yöntemi yerine, bir işlev çağrısına olası yeni bir yorum ekliyoruz f(args).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.