Scala xây dựng quá tải?


135

Làm thế nào để bạn cung cấp các nhà xây dựng quá tải trong Scala?

Câu trả lời:


186

Đáng để đề cập một cách rõ ràng rằng các Nhà xây dựng phụ trợ trong Scala phải gọi câu trả lời của nhà xây dựng chính (như trong câu trả lời của Landon9720) hoặc một nhà xây dựng phụ trợ khác từ cùng một lớp, là hành động đầu tiên của họ. Họ không thể đơn giản gọi hàm tạo của lớp cha một cách rõ ràng hoặc ngầm như trong Java. Điều này đảm bảo rằng hàm tạo chính là điểm duy nhất để vào lớp.

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: Ví dụ xấu? Không có nhà xây dựng thứ hai và thứ ba, người dùng vẫn có thể gọi new Foo(x=2,z=4)new Foo(z=5)nếu bạn thay đổi dòng đầu tiên của mình thànhclass Foo(x: Int = 0, y: Int = 0, z: String) {
user2987828

Các đối số được đặt tên / Mặc định không xuất hiện cho đến Scala 2.8.
Jon McAuliffe

2
Sẽ đáng để đề cập đến cách sử dụng một hàm tạo quá tải. Nó không tầm thường rằng newtừ khóa là cần thiết ngay cả đối với các lớp trường hợp.
Độc giả

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

16

Kể từ Scala 2.8.0, bạn cũng có thể có các giá trị mặc định cho các tham số phương thức và phương thức. Như thế này

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)

Các tham số có giá trị mặc định phải xuất hiện sau các tham số không có giá trị mặc định trong danh sách tham số.


3
Điều này không làm việc cho các mặc định không tầm thường mặc dù. vì vậy class Foo(val x:Int, y:Int=2*x)không hoạt động.
subub

@ Jorgen Lundberg: bạn đã viết Tham số có giá trị mặc định phải xuất hiện sau tham số không có giá trị mặc định trong danh sách tham số. Đó là sai, new Foo(x=2,z=4)sẽ in Foo(2,0,4).
user2987828

@ user2987828 ý tôi là bạn không thể viết Foo mới (12, x = 2) bạn phải viết Foo mới (x = 2, 12). Bạn có thể viết Foo mới (12, y = 2), sau đó bạn sẽ nhận được Foo (12, 2, 0)
Jörgen Lundberg

10

Trong khi nhìn vào mã của tôi, tôi đột nhiên nhận ra rằng tôi đã làm quá tải một công cụ xây dựng. Sau đó tôi nhớ câu hỏi đó và quay lại để đưa ra một câu trả lời khác:

Trong Scala, bạn không thể quá tải các hàm tạo, nhưng bạn có thể làm điều này với các hàm.

Ngoài ra, nhiều người chọn làm cho applychức năng của một đối tượng đồng hành trở thành một nhà máy cho lớp tương ứng.

Làm cho lớp này trở nên trừu tượng và quá tải applychức năng để thực hiện khởi tạo lớp này, bạn có trình xây dựng quá tải của bạn.

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)}
}

Lưu ý rằng tôi xác định rõ ràng từng cái applyđể trả về Expectation[T], nếu không nó sẽ trả về một con vịt gõ Expectation[T]{val expected: List[T]}.


0

Thử cái này

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
  }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.