2016-01-15 107 views
1

我有以下Scala类:扩展类斯卡拉 - 新手询问

class ClassA (x2: Int, y2: Int) { 
    var x = x2 
    var y = y2 
} 


class ClassB (x2: Int, y2: Int, z2: Int) extends ClassA (x2, y2) { 
    var z = z2 
} 

如果类用作值对象,并没有任何的方法,是用有延长的ClassA ClassB的点?无论如何,我需要定义ClassB中的所有字段。

+0

为什么你需要定义B类中的字段呢? – Simon

+0

取决于您是否拥有适用于'ClassA'对象的代码,并且您希望它能处理'ClassA'的不同子类的实例。否则,我只是'案例类ClassB(x:Int,y:Int,z:Int)'。 – Jesper

+0

考虑使用'val's和特征:'特质C {val x:Int; val y:Int}'。然后'case class ClassA(x:Int,y:Int)扩展C'和'case class classB(x:Int,y:Int,z:Int)扩展C' – Jus12

回答

1

那么,没有方法你基本上不使用多态,所以继承的价值大大减少。对于严格的值对象使用case classes这样的:

case class ClassA(x:Int, y:Int) 
case class ClassB(x: Int, y: Int, z: Int) 

萨德的伎俩,也现在你的类有默认copyequalshashapply操作。 Aternatively,如果你正在处理大量的变量,你可以尝试组成:

case class ClassB(a: ClassA, z2: Int) 

或者,如果你可以用构造函数分配并愿意使用默认值,你能避免重新定义的东西,并用性状:

trait TraitA { 
    var x = 0 
    var y = 0 
} 

trait TraitB extends TraitA { 
    var z = 0 
} 

客观地说,这取决于你最终用这些做什么。根据我的经验,良好的面向对象设计通常最终会有方法。将数据和操作它的方法分组到一个单一的粘性cblack框中是整个想法。但是对于函数式编程,我最终使用了case类。

+0

特征方法的问题在于, t实例化一个特质,所以你需要创建一个扩展特质的类。 – Jesper

+0

尽管可以,但你当然可以创建一个匿名类。尝试'val x = new TraitB {}' –

1

的第一件事情,如果你的真实的例子并不比你提出你可以这样做什么更复杂:

class ClassA (var x: Int, var y: Int) 
class ClassB (x: Int, y: Int, var z: Int) extends ClassA(x, y) 

这是更简洁相当于但是,你仍然有样板的一个良好的数额。

要回答你是否应该使用继承的问题,你应该回答另一个问题:句子“类ClassB的对象也是类ClassA的对象”是真的,它是否遵守LSP。如果您要使用ClassB,那么需要ClassA,那么我认为继承是一个有效的决定。

或者,你可以去作曲,让ClassB包含ClassA的实例,无论看起来更合乎逻辑。

我也想鼓励你使用不可变类,如果你决定你的类是不相关的,或者你使用组合。你会得到一个免费的copy方法,可以让你轻松“修改”你的对象,还有更多。