스칼라 생성자 과부하?


135

스칼라에서 오버로드 된 생성자를 어떻게 제공합니까?

답변:


186

스칼라의 Auxiliary Constructors는 기본 생성자 (landon9720의 응답에서와 같이) 응답 또는 첫 번째 조치와 동일한 클래스의 다른 보조 생성자를 호출해야한다는 점을 명시 적으로 언급 할 가치가 있습니다. Java에서와 같이 단순히 수퍼 클래스의 생성자를 명시 적 또는 암시 적으로 호출 할 수 없습니다. 이를 통해 기본 생성자가 클래스의 유일한 진입 점이됩니다.

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 : 나쁜 예? 두 번째와 세 번째 생성자가 없으면, 사용자는 여전히 호출 할 수 있습니다 new Foo(x=2,z=4)그리고 new Foo(z=5)당신이 당신의 첫 번째 라인을 변경하는 경우class Foo(x: Int = 0, y: Int = 0, z: String) {
user2987828

명명 된 / 기본 인수는 Scala 2.8까지 도착하지 않았습니다.
Jon McAuliffe

2
오버로드 생성자를 사용하는 방법을 언급 할 가치가 있습니다. 그것은 것을 사소한 아니다 new키워드는 경우에도 클래스가 필요합니다.
Readren

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

16

Scala 2.8.0부터 생성자 및 메소드 매개 변수에 대한 기본값을 가질 수도 있습니다. 이렇게

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)

기본값이있는 매개 변수는 매개 변수 목록에서 기본값이없는 매개 변수 뒤에 와야합니다.


3
그러나 사소한 기본값에는 작동하지 않습니다. 그래서 class Foo(val x:Int, y:Int=2*x)작동하지 않습니다.
subsub February

@ Jörgen Lundberg : 당신은 기본값을 가진 매개 변수는 매개 변수 목록에서 기본값이없는 매개 변수 뒤에 와야한다고 썼습니다. 잘못되어 new Foo(x=2,z=4)인쇄 Foo(2,0,4)됩니다.
user2987828

@ user2987828 의미하는 바는 새로운 Foo (12, x = 2)를 쓸 수 없다는 것입니다. 새로운 Foo (x = 2, 12)를 작성해야합니다. 당신은 새로운 푸 쓸 수 있습니다 (12, Y = 2), 당신은 푸 (12, 2, 0)을 얻을 것이다
요르겐 룬드

10

내 코드를 보면서 갑자기 생성자에 과부하가 걸린다는 것을 깨달았습니다. 나는 그 질문을 기억하고 또 다른 대답을하기 위해 돌아왔다.

스칼라에서는 생성자를 오버로드 할 수 없지만 함수를 사용하여이를 수행 할 수 있습니다.

또한 많은 사람들 apply이 컴패니언 객체 의 기능을 각 클래스의 팩토리로 선택합니다.

이 클래스를 추상화하고 apply함수를 오버로드하여이 클래스 를 구현-인스턴스화하면 오버로드 된 "생성자"가 있습니다.

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

명시 적으로 각각 apply반환하도록 정의합니다 Expectation[T]. 그렇지 않으면 duck-typed 반환합니다 Expectation[T]{val expected: List[T]}.


0

이 시도

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
  }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.