2017-04-12 94 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

感谢深度解读。 –