2012-11-06 33 views
5

Tôi gặp sự cố với mã sau. Nó không biên dịch. Có ai có ý tưởng về cách làm cho nó biên dịch mà không sử dụng asInstanceOf [SomeImpl] hoặc khớp mẫu.Loại thông số cụ thể trong Phân lớp không thể

Tôi đang nghĩ đến một số thông số loại, sử dụng giới hạn trên hoặc dưới.

object InherenceTryout extends App { 

    import someimpl._ 

    val list = List(SomeImpl("A"), SomeImpl("B")) 
    val result = new SomeHandler().handleBaseList(list) 

    println("%s->%s" format (list, result)) 

} 

package base { 

    // Defines that a 'Base' object can create a new 
    // 'Base' object where another 'Base' object is mixed in 
    // Does not define how the mixing will take place 
    trait Base { 
    def mix(other: Base): Base 
    } 

    // Defines how a default 'Base' object gets mixed into a list of 'Base' objects 
    trait BaseHandler { 
    def defaultBase: Base 
    def handleBaseList(list: List[Base]): List[Base] = list.map(b => b.mix(defaultBase)) 
    } 

} 

package someimpl { 

    import base._ 

    // Some implementation of 'Base' 
    // Defines how a new 'SomeImpl' object is created by mixing in another 
    // 'SomeImpl' object 

    // ERROR: 
    // class SomeImpl needs to be abstract, since method mix in trait Base of type (other: base.Base)base.Base is not defined 
    // (Note that base.Base does not match someimpl.SomeImpl: class SomeImpl in 
    // package someimpl is a subclass of trait Base in package base, but method parameter types must match exactly.) 
    case class SomeImpl(id: String) extends Base { 
     def mix(other: SomeImpl): SomeImpl = SomeImpl("[%s|%s]" format (id, other.id)) 
    } 

    // Defines the default 'SomeImpl' object 
    class SomeHandler extends BaseHandler { 
    def defaultBase = SomeImpl("D") 
    } 

} 

Trả lời

4

Dùng tham số type:

package base { 

    trait Base[T <: Base[T]] { 
    def mix(other: T): T 
    } 

    trait BaseHandler[T <: Base[T]] { 
    def defaultBase: T 
    def handleBaseList(list: List[T]): List[T] = 
     list.map(b => b.mix(defaultBase)) 
    } 

} 

package someimpl { 

    import base._ 

    case class SomeImpl(id: String) extends Base[SomeImpl] { 
    def mix(other: SomeImpl): SomeImpl = SomeImpl("[%s|%s]" format (id, other.id)) 
    } 

    class SomeHandler extends BaseHandler[SomeImpl] { 
    def defaultBase = SomeImpl("D") 
    } 

} 
+0

Câu trả lời này khá thú vị, nhưng có lẽ có một giải pháp khác mà thông số loại có thể được suy ra. Có lẽ bằng cách đặt nó vào phương pháp trộn? (thực ra tôi đã thử điều đó nhưng không thành công) – wwagner4

Các vấn đề liên quan