Scala constructor overload?


135

Bagaimana Anda menyediakan konstruktor kelebihan beban di Scala?

Jawaban:


186

Perlu disebutkan secara eksplisit bahwa Konstruktor Tambahan di Scala harus memanggil jawaban konstruktor utama (seperti pada landon9720), atau konstruktor bantu lain dari kelas yang sama, sebagai tindakan pertama mereka. Mereka tidak bisa begitu saja memanggil konstruktor superclass secara eksplisit atau implisit seperti yang mereka dapat di Jawa. Ini memastikan bahwa konstruktor utama adalah satu-satunya titik masuk ke kelas.

class Foo(x: Int, y: Int, z: String) {  
  // default y parameter to 0  
  def this(x: Int, z: String) = this(x, 0, z)   
  // default x & y parameters to 0
  // calls previous auxiliary constructor which calls the primary constructor  
  def this(z: String) = this(0, z);   
}

@ Jon McAuliffe: Contoh buruk? Tanpa konstruktor kedua dan ketiga, pengguna masih dapat menelepon new Foo(x=2,z=4)dan new Foo(z=5)jika Anda mengubah baris pertama Anda keclass Foo(x: Int = 0, y: Int = 0, z: String) {
user2987828

Argumen Bernama / Default tidak tiba sampai Scala 2.8.
Jon McAuliffe

2
Perlu disebutkan bagaimana menggunakan konstruktor yang berlebihan. Bukan sepele bahwa newkata kunci diperlukan bahkan untuk kelas kasus.
Readren

33
 class Foo(x: Int, y: Int) {
     def this(x: Int) = this(x, 0) // default y parameter to 0
 }

16

Pada Scala 2.8.0 Anda juga dapat memiliki nilai default untuk parameter konstruktor dan metode. Seperti ini

scala> class Foo(x:Int, y:Int = 0, z:Int=0) {                           
     | override def toString() = { "Foo(" + x + ", " + y + ", " + z + ")" }
     | }
defined class Foo

scala> new Foo(1, 2, 3)                                                    
res0: Foo = Foo(1, 2, 3)

scala> new Foo(4)                                                          
res1: Foo = Foo(4, 0, 0)

Parameter dengan nilai default harus datang setelah yang tanpa nilai default dalam daftar parameter.


3
Ini tidak bekerja untuk standar non-sepele. jadi class Foo(val x:Int, y:Int=2*x)tidak bekerja.
subsub

@ Jörgen Lundberg: Anda menulis Parameter dengan nilai default harus datang setelah yang tanpa nilai default dalam daftar parameter. Itu salah, new Foo(x=2,z=4)akan dicetak Foo(2,0,4).
user2987828

@ user2987828 yang saya maksud adalah Anda tidak dapat menulis Foo baru (12, x = 2) Anda harus menulis Foo baru (x = 2, 12). Anda dapat menulis Foo baru (12, y = 2), maka Anda akan mendapatkan Foo (12, 2, 0)
Jörgen Lundberg

10

Sambil melihat kode saya, saya tiba-tiba menyadari bahwa saya melakukan overload pada konstruktor. Saya kemudian ingat pertanyaan itu dan kembali untuk memberikan jawaban lain:

Di Scala, Anda tidak bisa membebani konstruktor, tetapi Anda bisa melakukan ini dengan fungsi.

Juga, banyak yang memilih untuk menjadikan applyfungsi objek pendamping sebagai pabrik untuk kelas masing-masing.

Membuat kelas ini abstrak dan membebani applyfungsi untuk mengimplementasikan-instantiate kelas ini, Anda memiliki "konstruktor" kelebihan beban Anda:

abstract class Expectation[T] extends BooleanStatement {
    val expected: Seq[T]}

object Expectation {
    def apply[T](expd:     T ): Expectation[T] = new Expectation[T] {val expected = List(expd)}
    def apply[T](expd: Seq[T]): Expectation[T] = new Expectation[T] {val expected =      expd }

    def main(args: Array[String]): Unit = {
        val expectTrueness = Expectation(true)}
}

Perhatikan bahwa saya secara eksplisit menentukan masing apply- masing untuk kembali Expectation[T], jika tidak maka akan mengembalikan bebek yang diketik Expectation[T]{val expected: List[T]}.


0

Coba ini

class A(x: Int, y: Int) {
  def this(x: Int) = this(x, x)
  def this() = this(1)
  override def toString() = "x=" + x + " y=" + y
  class B(a: Int, b: Int, c: String) {
    def this(str: String) = this(x, y, str)
    override def toString() =
      "x=" + x + " y=" + y + " a=" + a + " b=" + b + " c=" + c
  }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.