Scala의 "new"키워드


95

아주 간단한 질문이 있습니다. Scala에서 객체를 만들 때 새 키워드를 언제 적용해야합니까? Java 객체 만 인스턴스화하려고 할 때입니까?

답변:


145

의 자체 생성자 new를 참조 하려면 키워드를 사용 하십시오 class.

class Foo { }

val f = new Foo

new컴패니언 객체의 apply메서드를 참조하는 경우 생략 :

class Foo { }
object Foo {
    def apply() = new Foo
}

// Both of these are legal
val f = Foo()
val f2 = new Foo

케이스 클래스를 만든 경우 :

case class Foo()

Scala는 비밀리에 동반자 객체를 생성하여 다음과 같이 변환합니다.

class Foo { }
object Foo {
    def apply() = new Foo
}

그래서 당신은 할 수 있습니다

f = Foo()

마지막으로 컴패니언 apply 메서드가 생성자에 대한 프록시 여야 한다는 규칙이 없습니다 .

class Foo { }
object Foo {
    def apply() = 7
}

// These do different things
> println(new Foo)
test@5c79cc94
> println(Foo())
7

그리고 Java 클래스에 대해 언급 했으므로 예-Java 클래스에는 apply메서드 와 함께 동반 객체가 거의 없으므로 new실제 클래스의 생성자 를 사용해야합니다 .


1
Java 클래스는 동반 객체를 가질 수 없습니다. Java 클래스의 팩토리로 작동 할 수있는 객체를 가질 수 있지만이 객체는 동반 객체가 아닙니다.
kiritsuku

@Antoras Scala 클래스는 Java 바이트 코드로 컴파일되고 컴파일 된 형태로 배포 될 수 있으므로 Scala는 실제 Scala 동반자와 정적 MODULE $ 멤버가있는 Foo $라는 클래스의 차이점을 구분할 수 있습니까?
Owen

1
scalac은 컴패니언 클래스와 동일한 파일에서 컴패니언 객체를 선언해야하므로 이와 다를 수 있다고 생각합니다. 동반자 "속성"은 Scala에만 존재하고 Bytecode 수준의 scalac에는 존재하지 않기 때문에 사양을 준수하는지 확인하기 위해 Bytecode가 아닌 Scala 코드를 확인해야합니다.
kiritsuku

1
Scala에서 new 키워드를 사용하지 않는 Java 클래스의 예가 있습니까?
Bober02

또한 컴패니언 객체의 메서드는 클래스의 정적 메서드를 통해 액세스 할 수 있으며 나중에 "컴패니언"을 정의하는 Java 클래스에서는 발생하지 않습니다.
drexin 2012 년

16

Java 객체 만 인스턴스화하려고 할 때입니까?

전혀. new스칼라에서 생략하는 일반적인 경우는 두 가지 입니다. 싱글 톤 객체 (정적 함수를 저장하는 데 자주 사용되며 자바에서 볼 수있는 것과 유사한 일종의 팩토리로 사용됨) :

scala> object LonelyGuy { def mood = "sad" }
defined module LonelyGuy

scala> LonelyGuy
res0: LonelyGuy.type = LonelyGuy$@3449a8

scala> LonelyGuy.mood
res4: java.lang.String = sad

케이스 클래스를 사용하는 경우 (실제로 아래에는 클래스 + 객체 = 컴패니언 패턴이 있습니다. 예를 들어 같은 이름의 클래스와 객체를 가짐) :

scala> case class Foo(bar: String) 
defined class Foo


scala> Foo("baz")
res2: Foo = Foo(baz)

따라서 간단한 클래스로 작업 할 때 규칙은 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")

보너스로 스칼라에는 익명의 클래스가 있으며 다음과 같이 구성 할 수 있습니다.

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

1
괜찮 으세요?
Jacob B

0

Java 객체 만 인스턴스화하려고 할 때입니까?

Dotty를 기반으로 하는 Scala 3 (2020 년 중반, 8 년 후 출시 예정)을 사용 합니다.

이 스레드에서new 와 같이 Scala 3은 " " 을 (를) 삭제 합니다.

생성자 응용 프로그램은 적용 메서드가 구현되지 않은 경우에도 간단한 함수 호출 구문을 사용하여 클래스의 인스턴스를 만들 수 있습니다.

예:

class StringBuilder(s: String) {
   def this() = this(s)
}

StringBuilder("abc")  // same as new StringBuilder("abc")
StringBuilder()       // same as new StringBuilder()

Creator 응용 프로그램은 지금까지 케이스 클래스에 대해서만 제공된 기능을 일반화하지만이를 달성하는 방법은 약간 다릅니다.
자동 생성 된 적용 메서드 대신 함수 호출에 가능한 새로운 해석을 추가합니다 f(args).

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