我正在练习在线书籍《Scala编程》第一版中有关特征(trait)的章节。
这里有两个例子展示了特征的强大之处,分别是丰富薄接口和可叠加修改。以下是实现代码片段:
// example 1
trait Relation[T]
{
def compare(that: T): Int
def <(that: T) = compare(that) < 0
def >(that: T) = compare(that) > 0
def <=(that: T) = compare(that) <= 0
def >=(that: T) = compare(that) >= 0
}
// example 2
trait Doubling extends IntQueue
{
abstract override def put(a: Int) { super.put(a*2) }
}
以上代码可以正常编译。
我对abstract
修饰符的存在很好奇,所以在示例1中,我首先在Relation::compare()
前面添加了一个abstract
修饰符。也许将abstract
标记为compare
是合理的,因为它将被子类重写。
// case 1
abstract def compare(that: T): Int
然后编译器就开始抱怨了。
Error:(19, 16) `abstract' modifier can be used only for classes; it should be omitted for abstract members
abstract def compare(that: T): Int
^
我认为这条信息表明在trait中不应该使用abstract
修饰符。因此,我尝试从示例2中的Doubling :: put中删除abstract
修饰符,就像这样:
// case 2
override def put(a: Int) { super.put(a*2) }
但编译器也发出了警告
Error:(35, 36) method put in class IntQueue is accessed from super. It may not be abstract unless it is overridden by a member declared `abstract' and `override'
override def put(a: Int) { super.put(a*2) }
^
我知道在这里使用override
修饰符的原因,但我不知道为什么编译器会抱怨我应该加上abstract
修饰符。在前面的情况下,编译器只是抱怨我只应该将abstract
放在类中吗?