2011-02-01 3 views
6

내가 기본 클래스가 있다고 가정특성과 추상적 인 유형

abstract class Base { 

    type B<: Base 

    def rep:String 

    def copy:B 
} 

class MyBase(override val rep:String) extends Base { 
    type B = MyBase 

override def copy = new MyBase(rep) 
} 

그때 사본이 (호출하는 적절한 유형 의미가 될 수 있도록 내가 반환 형식을 원하는에 대한 믹스 인, 같은 다른 특성을 추가하려고 mixin의 copy는 B를 적절한 유형으로 설정하여 mixin 유형을 반환합니다). 나는 이것을 컴파일 할 수 없었고 심지어 override 키워드가 어디로 가야 하는지를 이해할 수 없었다.

편집 : 나는 적절한 타입 B를 선언하고 사본은 DecBase을 반환하도록, DecBase에 대한 방법을 복사하고, 또한, 왜 '수상 어떻게

abstract class Base { 


    type B <: Base 

    def rep:String 

    def copy:B 

} 

class MyBase(val rep:String) extends Base { 

    type B = MyBase 

    def copy = new MyBase(rep) 
} 


trait DecBase extends Base { 

    abstract override def rep = "Rep: "+super.rep 
} 

내 질문은 예를 정제 한 이 컴파일?

println(((new MyBase("ofer") with DecBase)).rep) 

이것은 자바에서 성취했을 것입니다. 재귀 적 제네릭 유형을 사용하면 다소 불쾌합니다. 나는 Scala에서 더 좋은 것을 할 수 있다고 확신한다. 사용

편집

trait DecBase extends Base { 

    override type B = DecBase 
    abstract override val rep= "Dec:"+super.rep 
    abstract override def copy = new MyBase(rep) with DecBase 
} 

나는

error: overriding type B in class MyBase, which equals com.amadesa.scripts.MyBase; 
type B in trait DecBase, which equals com.amadesa.scripts.DecBase has incompatible type 
println(((new MyBase("ofer") with DecBase)).rep) 

error: overriding type B in class MyBase, which equals com.amadesa.scripts.MyBase; 
type B in trait DecBase, which equals com.amadesa.scripts.DecBase has incompatible type 
abstract override def copy = new MyBase(rep) with DecBase 

답변

2

나는이

trait MixIn extends Base { 
    override B = MixinBase 
    override def copy = new MixinBase(rep) 
} 
같이 보입니다에 믹스를 다음과 같은 컴파일러 오류 가정 얻을

overrideMyBase은 문제의 일부입니다. 그것은 불필요하고 컴파일러를 혼란스럽게합니다. override 필요하게 사실 Basecopy이 구현되어있는 경우

는, 당신은 방법을 사용하도록 컴파일러에 알려야합니다. 그것이 분명하지 않다면, 손을 던져 오류를 발생시킵니다. 이 시도.

val b = new MyBase(rep) with MixIn { 
    override def copy = MixIn.super.copy 
} 

MixIn.super.copy은 원하는 전화를 겁니다.

Scala Class Linearization에서이 페이지를 검토하여 유형의 메소드 구현과 경쟁하는 경우 어떻게되는지 이해할 수 있습니다.

편집 : 오, 완전히 다른 문제입니다. case MyBase(val rep:String)에 있습니다. val이 불변이라고 가정하기 때문에 val을 def로 재정의 할 수 없습니다. def 또는 var를 val로 재정의 (override) 할 수는 있지만, 그 반대는 아닙니다. 확인하십시오 :

trait DecBase extends Base { 
    abstract override val rep = "Rep: "+super.rep 
} 

다음 번에 컴파일러 오류를 포함하십시오. 문제가 무엇인지 쉽게 알 수 있습니다.

+0

나는 질문을 세련했다. – user44242

+0

다시 편집하여 이번에는 컴파일러 오류가 발생했습니다. 중요한 것은 copy 메소드의 올바른 리턴 유형입니다. – user44242

+0

이제 문제가 발생합니다. DecBase는 MyBase의 하위 유형이 아니므로 B를 B로 대체 할 수 없습니다. 하지만이를 수정 한 후에도 여전히 오류가 발생합니다. 컴파일러는 B = MyBase 유형을 무시하는 것 같지 않지만 다른 것일 수 있습니다. – sblundy

0

어떻게 든 val repMyBase에 연결되어 있다고 생각합니다. def rep을 구현하지 않으려면 MyBase 추상을 정의해야합니다.이 도움이

abstract class Base { 
    type B <: Base 
    def rep:String 
    def copy: B 
} 

class MyBase(val repVal: String) extends Base { 
    type B = MyBase 
    def rep = repVal 
    def copy = new MyBase(repVal) 
} 


trait DecBase extends Base { 
    abstract override def rep = "Rep: " + super.rep 
} 

println(((new MyBase("ofer"))).rep) // prints: ofer 
println(((new MyBase("ofer") with DecBase)).rep) // prints: Rep: ofer 

희망 : 여기

예를 노력하고 있습니다.

val myBase: MyBase = new MyBase("alone") 
val myBaseCopy: MyBase = myBase.copy 

val decBase: DecBase = new MyBase("mixed") with DecBase 
val decBaseCopy: DecBase = decBase.copy 

type 선언에서 평등 대신 형의 경계를 사용하도록 코드를 다시 작성 (도 val rep을 사이의 불일치를 해결하기 위해 수 있습니다 : 나는 그것을 이해

+0

Nope. 스칼라에서 def 나 val을 갖는 것은 서로 바꿔서 사용할 수 있습니다. 발 rep 물건은 대표의 구현이다. – user44242

+0

죄송합니다, 나는 근본적인 것을 잊어 버린 것 같습니다 :) 지적 해 주셔서 감사합니다! – tenshi

0

그래서, 목표는 할 수있을 것입니다 및 def rep) 다른 컴파일러 오류가 숨어있는 :

abstract class Base { 
    type B <: Base 
    def rep: String 
    def copy: B 
} 

class MyBase(_rep: String) extends Base { 
    type B <: MyBase 
    def rep = _rep 
    def copy = new MyBase(rep) 
} 

trait DecBase extends Base { 
    override type B <: DecBase 
    override abstract def rep = "Rep: " + super.rep 
} 

를이 지금 MyBase.copyMyBase 또는 서브 클래스, 및 DecBase.copy 쉬를 반환해야 함을 말한다 ould는 DecBase 또는 하위 클래스를 반환합니다. 그게 니가 원하는거야, 맞지? 이제 결과 컴파일러 오류는 분명하다 :

temp.scala:10: error: type mismatch; 
found : this.MyBase 
required: MyBase.this.B 
    def copy = new MyBase(rep) 
      ^
one error found 

그래서 당신은 반환하고 MyBase하지만 당신은 정말 예를 들어, 서브 클래스를 반환해야 new MyBase(rep) 대신 new MyBase(rep) with DecBase을 반환하려고하지만 객체가 new MyBase(...) with DecBase으로 선언 된 경우에만 반환하려고합니다. 나는 그걸 할 방법을 모른다. 아마 adding a trait after an object has been constructed을보아야 할 것이다.

+0

Base 및 MyBase로 제한하고 DecBase를 잊어 버린 경우에도 컴파일되지 않습니다. 컴파일러가 불평 : 오류 : 형식 불일치; 발견 : com.amadesa.scripts.MyBase 필수 : ​​MyBase.this.B def copy = new MyBase (담당자) – user44242

+1

정확합니다. 'DecBase.copy'가'DecBase'를 반환하기를 원하지만'MyBase'가 실제로 객체를 생성하고'MyBase'가'DecBase'에 대해 아무것도 모르기 때문에 불가능합니다. 'DecBase'가'새로운 MyBase (rep)'라인을'Decbase로 새로운 MyBase (rep) '라인으로 어떻게 든 바꾸기를 기대하고 있습니다. – Steve

관련 문제