Scala의 개인 및 보호 생성자


109

Scala에 명시적인 기본 생성자가없는 경우 클래스 본문의 내용 만 궁금합니다.

특히, 개인 또는 보호 된 생성자 패턴, 즉 컴패니언 객체 또는 다른 클래스 또는 객체의 메서드를 통해 생성을 제어하는 ​​것은 명백한 구현이 없을 수 있다고 생각합니다.

내가 잘못? 그렇다면 어떻게 수행됩니까?


당신은 Scala 싱글 톤 (object 키워드, 즉)을 가질 수 있고, 당신의 클래스를 그 싱글 톤 내에서 private으로 정의 할 수 있고, 당신의 객체를 생성하기위한 싱글 톤의 메소드를 가질 수 있습니다.
Paggas

@Paggas, 불행히도 범위를 벗어난 비공개로 표시된 클래스의 인스턴스를 반환하면 해당 범위의 컴패니언 개체에있는 메서드에서 반환 된 경우에도 컴파일되지 않습니다.
Don Mackenzie

이것은 Scalaz 소스 코드 전체에서 상당히 많이 수행됩니다. 이 개념은 추상 대수 데이터 유형 이라고도 합니다.
토니 모리스

답변:


190

다음과 같이 클래스 이름과 매개 변수 목록 사이에 적절한 키워드를 삽입하여 기본 생성자를 private / protected로 선언 할 수 있습니다.

class Foo private () { 
  /* class body goes here... */
}

감사합니다 Aleksander, 이것이 스칼라 책 중 하나에 있는지 또는 언어 사양에 있는지 알려주시겠습니까? 아직 찬성 할 수 없어서 죄송합니다.
Don Mackenzie

방금 "Programming Scala"의 생성자에 대한 설명 (92-95 페이지)을 훑어 봤는데 거기에 언급되지 않았습니다. 실제로 이전 변경 로그에서 귀하의 질문에 대한 답을 찾았지만 이전에는 다른 곳에서 언급 한 적이 없습니다. 링크 : scala-lang.org/node/43#2.4.0
Aleksander Kmetec

18
"스칼라 프로그래밍"의 페이지 414. Wampler의 프로그래밍 스칼라 97 페이지. Subramaniam의 프로그래밍 스칼라 60 페이지. 지금 확인해 볼 수있는 Beginning Scala의 PDF가 없습니다.
Daniel C. Sobral

오, 지금 97 페이지에 있습니다. 감사합니다.
Aleksander Kmetec

1
더 많은 연구를 해주셔서 감사합니다. Wampler 책을 받았지만 제 휴대폰으로 만 완전히 읽지 않았지만 Odersky 책을 놀랍게도 잘 보완한다는 것을 알게되었습니다.
Don Mackenzie

64

Aleksander 의 대답은 정확하지만 Scala의 프로그래밍 은 추가 대안을 제공합니다.

sealed trait Foo {
 // interface
}

object Foo {
  def apply(...): Foo = // public constructor

  private class FooImpl(...) extends Foo { ... } // real class
}

18
몇 년 후 튀어 나온 말 : 나는 이것이 질문에 대한 좋은 대답이지만 문제에 대한 나쁜 해결책이라고 생각합니다. 어떤 미래의 프로그래머가 Aleksander의 코드를 사용한다면 그는 "아, 기본 생성자는 비공개이지만 다른 생성자는 그렇지 않습니다."라고 말할 것입니다. 그 프로그래머가 Daniel의 코드를 보면 "아, 그들은 기본 생성자를 비공개로 표시 할 수없는 Scala를 보상하기 위해 Factory 패턴을 사용하고 있습니다. 잠깐만, Scala 는 기본 생성자를 비공개로 표시 할 수 있습니다 ! 여기에?!?" 즉, 잘못된 WTF / LOC 비율입니다.
Malvolio

20
@Malvolio 나는 동의하지 않습니다. 이 패턴은 기본 생성자를 비공개로 만들뿐만 아니라 구현 도 사용자가 인터페이스 (특성)를 사용하도록합니다. 그것은 그 자체의 가치가 있습니다. 언어를 모르기 때문에 무언가를 생각하는 사람은 piffle! Kenny Tilton의 말을 인용하려면 빌어 먹을 언어를 배우십시오 !
다니엘 C. 소브랄

7
이 접근 방식은 new키워드를 사용하지 않음을 의미한다는 것을 어딘가에서 언급해야합니다 .
Travis Parks

1
이 접근 방식의 한 가지주의 사항은 누군가 자신의 구현을 통해 Foo를 인스턴스화 할 수 있다는 것입니다. 이는 시공을 통제하는 이유에 따라 장단점으로 볼 수있다.
aij

1
@aij True, 그래서 더 이상 일어날 수 없도록 만들었습니다. :)
Daniel C. Sobral
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.