2017-04-12 128 views
0

//文件Animal.scala斯卡拉 - 對象擴展的抽象類和取參數

abstract class Animal { 

    val name: String 

    def getSomething(tClass: TypeClass): String = { 
     tClass.tName.split('.').lift(0) 
    } 

    def apply(tClass: TypeClass): SomeOtherClassType = { 
     // something... 

    } 

//文件:DogSpike,這是用於某些特定情況下(覆蓋 基class val)

object DogSpike extends Animal { 

    override val name: String = "Spike" 
} 

該調用隨後(電話申請)
myTransformation(() => DogSpike(this))

現在我想創造一個更通用的對象,一個可以傳遞參數,但我不能。

它的工作,以創建從動物,它有一個參數的派生類對象,並能夠使用的應用調用

object TheDog(name: String) extends Animal { 

    override val name: String = "Spike" 
//... 
} 

不知道如何隱含調用Animal.apply爲TheDog對象,我可以通過一個參數(名稱)
myTransformation(() => TheDog(this))

// also this seems to be incorrect "*Wrong top statement declaration*" 
object TheDog(val n: String) extends Animal { 
    override val name: String = n 
//... 
} 

回答

2

由於*Wrong top statement declaration*(我只能這樣理解你的問題的一部分) - 你不能有構造函數對象object是單身,所以你應該使用的情況下,類(ADT):

final case class TheDog(name: String) extends Animal 

scala>TheDog("Spike") 
res2_2: TheDog = TheDog("Spike") 

val和伴侶的對象與apply爲case類自動添加,所以你不需要在Animal中定義你自己的applycase class TheDog(val name: String)case class TheDog(name: String)相同。

我也是用的,而不是抽象類trait S:

trait Animal { 

    val name: String 

    def getSomething: String = { 
     "Dog: " + name 
    } 

} 

我不明白你的TypeClass類型,但如果你真的想類型類:

trait Animal { 
    def name: String 
} 

final case class TheDog(name: String) extends Animal 
final case class TheCat(name: String) extends Animal 

implicit class RichDog(dog: TheDog){ 
    def getSomething: String = { 
     "Dog" + dog.name 
    } 
} 

implicit class RichCat(cat: TheCat){ 
    def getSomething: String = { 
     "Cat: " + cat.name 
    } 
} 

scala> TheDog("Spike").getSomething 
res4_5: String = "DogSpike" 
scala> TheCat("Tom").getSomething 
res4_6: String = "Cat: Tom" 

關於調用「隱含地」apply,我不知道爲什麼有人需要這個,但是:

trait AnimalFactory[A <: Animal] { 

    def apply(name: String)(implicit constructor: String => A) = constructor(name) 

} 

object TheeeDog extends AnimalFactory[TheDog] 

implicit def createDog(name: String) = TheDog(name) 

TheeeDog("Spike") 

當然,你必須提供createDog並使其爲客戶可見的,但它並沒有真正意義,如果你可以只使用抽象數據類型和定義附加要求apply S IN同伴對象:

case class TheMouse(name: String) 
    object TheMouse{ 
    def apply(isJerry: Boolean): TheMouse = if (isJerry) TheMouse("Jerry") else TheMouse("NotJerry") 
    } 

    TheMouse(true) 

如果你想添加一些參數的構造函數,只需添加:

class AnimalFactory(clazz: SomeClass){ 
     def doSomething = clazz.name 

     def apply(name: String) 
    } 

    val dogFactory = new AnimalFactory(dogClassDescriptor) 
    val catFactory = new AnimalFactory(catClassDescriptor) 

    dogFactory("Spike") 
    catFactory("Tom") 

你甚至可以創建工廠工廠(我不建議 - 這SOLU重刑看起來已經過於複雜):

object AnimalFactory{ //please don't use classes for that - avoiding `new` is not their purpose 
    def apply(clazz: SomeClass) = new AnimalFactory(clazz) 
    } 
    val dogFactory = AnimalFactory(dogClassDescriptor) 
    //or even `val spike = AnimalFactory(dogClassDescriptor)("Spike")` 

但還是有什麼意義,如果你可以只提供基本clazz無論是作爲一個成員或只是一個包裝:

final case class ClazzWrapper[T <: Animal](clazz: SomeClass, animal: T) 
+0

感謝深度解讀。 –