Saya punya pertanyaan yang sangat sederhana - kapan kita harus menerapkan kata kunci baru saat membuat objek di Scala? Apakah ketika kita mencoba untuk membuat contoh objek Java saja?
Jawaban:
Gunakan new
kata kunci ketika Anda ingin merujuk ke class
konstruktor milik sendiri:
class Foo { }
val f = new Foo
Abaikan new
jika Anda merujuk ke metode objek pendamping apply
:
class Foo { }
object Foo {
def apply() = new Foo
}
// Both of these are legal
val f = Foo()
val f2 = new Foo
Jika Anda telah membuat kelas kasus:
case class Foo()
Scala diam-diam membuat objek pendamping untuk Anda, mengubahnya menjadi ini:
class Foo { }
object Foo {
def apply() = new Foo
}
Jadi Anda bisa melakukannya
f = Foo()
Terakhir, perlu diingat bahwa tidak ada aturan yang mengatakan bahwa apply
metode pengiring harus berupa proxy untuk konstruktor:
class Foo { }
object Foo {
def apply() = 7
}
// These do different things
> println(new Foo)
test@5c79cc94
> println(Foo())
7
Dan, karena Anda menyebutkan kelas Java: ya - kelas Java jarang memiliki objek pendamping dengan sebuah apply
metode, jadi Anda harus menggunakan new
dan konstruktor kelas yang sebenarnya.
Apakah saat kami mencoba untuk membuat instance objek java saja?
Tidak semuanya. Ada dua kasus umum saat Anda mengabaikan new
dalam skala. Dengan objek tunggal (yang sering digunakan untuk menyimpan fungsi statis dan sebagai pabrik yang mirip dengan yang Anda lihat di java):
scala> object LonelyGuy { def mood = "sad" }
defined module LonelyGuy
scala> LonelyGuy
res0: LonelyGuy.type = LonelyGuy$@3449a8
scala> LonelyGuy.mood
res4: java.lang.String = sad
Dengan case kelas (sebenarnya, di bawahnya ada class + object = pola pendamping , misalnya memiliki class dan object dengan nama yang sama):
scala> case class Foo(bar: String)
defined class Foo
scala> Foo("baz")
res2: Foo = Foo(baz)
Jadi ketika Anda bekerja dengan kelas sederhana, aturannya sama dengan Java.
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")
Bonusnya, ada kelas anonim dalam scala, yang dapat dibuat seperti ini:
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
Apakah ketika kita mencoba untuk membuat contoh objek Java saja?
Dengan Scala 3 (yang akan dirilis pertengahan 2020, delapan tahun kemudian), berdasarkan Dotty : never.
Scala 3 akan " new
" turun , seperti di utas ini
Aplikasi pembuat memungkinkan untuk menggunakan sintaks panggilan fungsi sederhana untuk membuat instance kelas, bahkan jika tidak ada metode terapan yang diterapkan.
Contoh:
class StringBuilder(s: String) {
def this() = this(s)
}
StringBuilder("abc") // same as new StringBuilder("abc")
StringBuilder() // same as new StringBuilder()
Aplikasi pembuat menggeneralisasi fungsionalitas yang disediakan sejauh ini hanya untuk kelas kasus, tetapi mekanisme bagaimana hal ini dicapai sedikit berbeda.
Alih-alih metode penerapan yang dibuat secara otomatis, kami menambahkan kemungkinan interpretasi baru ke pemanggilan fungsif(args)
.