2016-07-31 5 views
1

ID를 나타내는 객체가 내 프로젝트에 있습니다.스칼라 값 클래스 다중 상속

ChairId, TableId, LampId라고합시다. 나는 그들 모두가 GenericId로부터 상속 받기를 바랍니다. 전화 할 수 있기를 원합니다. def f(x: GenericId) = x.id

id: String 하나만 보유하고 싶기 때문에 AnyVal을 확장하도록하고 싶습니다. 하지만 경우

sealed abstract class GenericId(val id: String) 
final case class ChairId(override val id: String) extends GenericId(id) 
final case class TableId(override val id: String) extends GenericId(id 

그리고 I :이 입력 한 ChairId.generate()

또한 내 특정 ID의 예를 생성 할 기능 generate 내가 좋아하는 뭔가를 입력하고 싶습니다 제공하기 위해 각 유형 싶습니다 GenericId는 AnyVal에서 상속 받았지만 지금까지 아무런 행운이 없었습니다./또한 GenericId를 특성으로 만들고 케이스 클래스가 GenericId로 AnyVal을 확장했지만 컴파일하지도 않았습니다./

Anot 그녀의 일을 TableId.generate() 함께 제공 할 수 있습니다. 그냥 기능을 generate 및 그 기본적으로 내 문제를 해결할 수 있지만 동반자 개체를 정의하지 않고 해결할 가능성이 있는지 궁금해? (즉, implicits을 통해 어떻게 든) 컴파일되지 않는 코드를 제공하기 위해 주석에 대한

// 편집

(나는 싶습니다) :

sealed abstract class AbstractId(val id: String) extends AnyVal 
final case class CatId(override val id: String) extends AbstractId(id) 
final case class DogId(override val id: String) extends AbstractId(id) 
+0

나는 당신이 여기서 무엇을 묻고 있는지 완전히 모르겠습니다. 질문이 여러 개인 경우 스택 오버플로 관련 질문을 여러 개로 나눌 수 있습니다. –

+0

시도한 것에 대한 코드 및 컴파일 오류를 포함하십시오. 나는 이것이 도움이 될 것이라고 생각한다. –

답변

3

값 클래스가이 방식으로 작동 할 수 몇 가지 이유.

먼저 documentation부터 값 클래스를 다른 클래스에서 확장 할 수 없으므로 AbstractIdAnyVal을 확장 할 수 없습니다. (Limitation #7)

scala> abstract class AbstractId(val id: String) extends AnyVal 
<console>:10: error: `abstract' modifier cannot be used with value classes 
     abstract class AbstractId(val id: String) extends AnyVal 
        ^

둘째, 경우에도은이 같은 다른 ID를 형질을 AbstractId 확인하고 정의

final case class DogId(val id: String) extends AnyVal with AbstractId 

.. 값 클래스의 사용이 적합하지 않을 당신의 왜냐하면 클래스 자체가 여전히 할당되기 때문입니다.

  1. 값 클래스가 다른 유형으로 처리됩니다 때

    값 클래스 실제로 인스턴스화 다음 allocation summary을 참조하십시오.

  2. 값 클래스가 배열에 할당됩니다.
  3. 패턴 일치와 같은 런타임 형식 테스트를 수행합니다.
+0

몇 초 동안 나를 이길 :) – pedrofurla

1

의심 명확히 할 가능성이 value classes SIP에서 일부 인용 :

값 클래스를 ...

  1. 는 ... 정확히 하나의 대중 유형이 값 클래스없는 발 매개 변수 만 기본 생성자가 있어야합니다.

  2. ... 다른 클래스에서 확장 할 수 없습니다.

1 당으로는 추상적 할 수 없습니다 2. 인코딩이 작동하지 않습니다.

값의 클래스는 보편적 인 특성을 확장 할 수 있습니다 및 자체를 확장 할 수 없습니다 :

다른주의가있다. 보편적 인 특성은 Any를 확장하는 특성이며, 을 def로 가지고 있으며 초기화하지 않습니다. 유니버설 특성은 값 클래스에 대해 기본 메서드의 상속을 허용하지만 할당의 오버 헤드는 이됩니다.

sealed trait AbstractId extends Any { def id: String } 
final case class CatId(id: String) extends AnyVal with AbstractId 
final case class DogId(id: String) extends AnyVal with AbstractId 

을하지만 당신은 AbstractId로 CATID 및 DogId을 사용하려는 경우 할당에만 발생 명심 : 당신의 마지막 조각을 기반으로 염두에두고 모든 것을,와

,이 작동 할 수 있습니다. 이해를 돕기 위해 SIP를 읽는 것이 좋습니다.