在Scala中重用对象的apply函数

时间:2016-04-10 19:45:15

标签: scala apply code-reuse

我使用apply方法有一个A类和工厂函数。

object A {
  def apply(a:String) {... new A}
  def apply(a:Int) {... new A}
  ...
}

class A(...) {
...
}

当我从A获得具有相同工厂方法的子类B.我有相同的生成B的应用方法。

object B {
  def apply(a:String) {... new B} // duplication
  def apply(a:Int) {... new B} // duplication 
  ...
}

class B(...) extends A {
...
}

我可以重用B中A的apply方法吗?

1 个答案:

答案 0 :(得分:2)

执行此操作的一种方法是定义包含常用方法的mixin特征,这将取决于抽象工厂函数。然后,伴随对象可以扩展这样的mixin,只实现创建相应实例的特定方式。

一个例子:

trait FooFactory[T] {
    def make(s:String, i:Int): T
    def apply(s:String):T = make(s, 0)
    def apply(i:Int):T = make("", i) 
}

class A(s:String = "", i:Int = 0) {
  def foo:String = s+i
  override def toString() :String = s"[$foo]"
}

// object A {
//   def apply(a:String): A = { new A(s=a)}
//   def apply(a:Int): A = { new A(i=a)}
// }

object A extends FooFactory[A] {
    def make(s:String, i:Int) = new A(s,i)
}

class B(s:String = "") extends A(s,-1){
  override def foo:String = s+":"+super.foo
}

// object B {
//   def apply(a:String):B = { new B(a)}
//   def apply(a:Int):B = { new B(a.toString)}
// }

object B extends FooFactory[B] {
    def make(s:String, i:Int) = new B(s)
}

如果需要访问目标类层次结构的特定方法,可以将类型约束为其子类型的类。

trait FooFactory[T <: A] {
    def make(s:String, i:Int): T
    def apply(s:String): T = make(s, 0).someAMethod()
}