2015-01-09 45 views
4

的同伴对象的代码复制我在我的Scala代码以下模式:如何避免在子类中

class A(x: Int) 
object A { 
    def apply(x: Int, y: Int) = new A(x + y) 
} 

class B(x: Int) extends A(x) 
object B { 
    def apply(x: Int, y: Int) = new B(x + y) 
} 

的施工方法是完全一样的,除了它们构造对象的类。我想避免这种代码重复,尤其是因为在我的真实代码中,我有几种应用方法,它们要长得多。

我该如何做到这一点?我如何删除此代码重复?

我想过这样的事情:

class A(x: Int) 
class B(x: Int) extends A(x) 

trait C[T <: A] { 
    def apply(x: Int, y: Int) = new T(x + y) 
} 

object A extends C[A] 
object B extends C[B] 

它不工作,因为T是不是一个班的,所以我不能做“的新T(X + Y)”。

+0

你真的不能在构造抽象。如果你愿意使'A'和'B'成为'case class'es,你可以在'C'中调用伴随对象*的(生成)'apply'方法*。 – lmm

回答

1

我会提出这样的解决方案:

class A(x: Int) 
class B(x: Int) extends A(x) 

trait C[+T <: A] { 
    def apply(x: Int, y: Int) = create(x + y) 
    protected def create(x: Int): T 
} 

object A extends C[A] { 
    override protected def create(x: Int) = new A(x) 
} 
object B extends C[B] { 
    override protected def create(x: Int) = new B(x) 
} 

GenericCompanion类看一看。这是Scala集合库的一部分,可以激发你: http://www.scala-lang.org/api/current/index.html#scala.collection.generic.GenericCompanion

+1

这确实不能解决代码重复,是吗? –

+1

它避免了“x + y”的重复,这是唯一重复的逻辑 –

3

在特定的情况下,你可以这样做

class A(x: Int) { 
    def this(x: Int, y: Int) = this(x + y) 
} 
class B(x: Int) extends A(x) 
2
class Adder[T](f: Int => T) { 
    def apply(x: Int, y: Int) = f(x + y) 
} 

class A(x: Int) 
object A extends Adder(new A(_)) 

class B(x: Int) extends A(x) 
object B extends Adder(new B(_))