2012-02-19 87 views
16

我想知道使用abstract关键字与trait组合的语义是什么。斯卡拉抽象性状的语义

如果性状没有定义任何抽象方法,在abstract关键字不会阻止我创建一个实例:

scala> abstract trait T 
defined trait T 

scala> new T{} 
res0: java.lang.Object with T = [email protected] 

在另一方面,如果性状确实定义了一个抽象的方法,我不能创建一个实例(没有实现,当然这种方法),无论是否abstract关键字存在与否:

scala> abstract trait T { def foo : Unit } 
defined trait T 

scala> new T{} 
<console>:9: error: object creation impossible, since method foo in trait T of type => Unit is not defined 
       new T{} 
       ^

scala> trait T { def foo : Unit } 
defined trait T 

scala> new T{} 
<console>:9: error: object creation impossible, since method foo in trait T of type =>  Unit is not defined 
       new T{} 
       ^

那么,什么是一个前面的abstract关键字210有用吗?

+2

您无法创建特质实例。当你说'新型T {}'你创建一个匿名对象的特点T. – sschaef 2012-02-19 13:27:12

回答

1

你没有创建特征的一个实例。特征不能被实例化。

您正在创建一个扩展特质的匿名类的实例。

一般而言,

new __t__ 

相当于

{ class __anonymous__ extends __t__; new __anonymous__ } 

(其中__anonymous__是匿名类是不可访问的用户程序的一个新鲜名称)。

这在section 6.10 Instance Creation Expressions of the Scala Language Specification中有详细说明。

那么,为什么你可以创建在第一种情况下的实例的原因,是因为你没有创建特征的一个实例(这是抽象的),但一个对象(不)。

在第二种情况下,您无法创建实例的原因是,如果您从某种东西继承,无论这是一个特质还是一个类,您最终必须在继承链的某处实现其抽象方法为了实例化它。在第一种情况下,没有抽象的方法来实施。

abstract关键字本身没有什么区别:特点是含蓄抽象,关键字是多余的。

+4

我觉得它混入你的意思是说,他正在创建一个匿名*类*,它具有特质的混入。 – 2012-02-19 15:11:42

+0

对不起,是的。一个对象,它是一个匿名类的实例,它是该特征的一个子类。唷。 – 2016-03-31 14:20:14