为什么Scala在具有特质的时候有课?
这似乎是一个愚蠢的问题,所以忍受我
考虑这个REPL会话: scala> trait T defined trait T scala> val t = new T <console>:8: error: trait T is abstract; cannot be instantiated val t = new T ^ scala> val t = new T {} t: java.lang.Object with T = $anon$1@78db81f3 scala> class C defined class C scala> val c = new C c: C = C@170a6001 我们可以像一个类一样使用特征,除了我们必须在新的T之后添加{}。实际上,我们基本上将T混合到java.lang.Object中,这实际上对我来说很有意义。 如果我们有成员,则只需添加{}: scala> trait T2 { val s = "test" } defined trait T2 scala> val t2 = new T2 <console>:8: error: trait T2 is abstract; cannot be instantiated val t2 = new T2 ^ scala> val t2 = new T2 {} t2: java.lang.Object with T2 = $anon$1@6a688d6f scala> t2.s res0: java.lang.String = test scala> class C2 { val s = "test" } defined class C2 scala> val c2 = new C2 c2: C2 = C2@73ea7821 scala> c2.s res1: java.lang.String = test 如果我们有抽象成员,那么特征声明实际上会比较短的几个字符,更重要的是,我的眼睛更加一致(不需要记住将抽象放在你的声明之前): scala> trait T3 { val s: String } defined trait T3 scala> val t3 = new T3 { val s = "test" } t3: java.lang.Object with T3 = $anon$1@1f2f0ce9 scala> abstract class C3 { val s: String } defined class C3 scala> val c3 = new C3 { val s = "test" } c3: C3 = $anon$1@207a8313 如果你忘记你必须定义一些成员,这两种方式都给你编译错误: scala> val badt3 = new T3 {} <console>:7: error: object creation impossible,since value s in trait T3 of type String is not defined val badt3 = new T3 {} scala> class BadC3 { val s: String } <console>:8: error: class BadC3 needs to be abstract,since value s is not defined class BadC3 { val s: String } 如果我们尝试做更复杂的事情,那么特征的力量自然会变得更加明显: scala> val t4 = new T with T2 t4: java.lang.Object with T with T2 = $anon$1@479e0994 scala> val c4 = new C with C2 <console>:9: error: class C2 needs to be a trait to be mixed in val c4 = new C with C2 那么我再问一次,为什么Scala会在课堂上显得更加简单和强大? 我认为原因是与Java的概念和实际兼容性,但我不知道代码兼容性是否可以在后台维护。据我所知,Scala的特性只是在幕后成为Java类,所以为什么不能反过来呢,Scala认为Java类基本上是特征? 相关的所有这一切,为什么不允许放弃大括号中不必要的?例如: val t = new T 在这一点上,作为一个用户,特征与目前的Scala类别是无法区分的,当然更好。 解决方法
性状和类之间有几个区别:
一个特征不能得到构造函数参数。这个限制可能会在某些时候解除,但这是一个很难的问题。特征可以在层次结构中多次继承,并且每个实例化可能为构造函数参数赋予不同的值 我不认为课堂和特质之间的区别将会消失,主要是因为最后两项。但如果第一点得到解决,它们可能会变得更容易使用。关于没有{}的实例化,这是一个可以添加的方便,但我个人不喜欢它:每个实例化都会创建一个新类(一个匿名的),应该向程序员说明是这样的。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |