Ç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:
Kendi kurucusuna new
başvurmak istediğinizde anahtar kelimeyi kullanın class
:
class Foo { }
val f = new Foo
new
Tamamlayıcı nesnenin apply
yö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 apply
yöntemle eşlik eden nesneler içerir , bu nedenle new
ve gerçek sınıfın yapıcısını kullanmalısınız.
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
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 ekliyoruzf(args)
.