Why does the compiler complain when using an abstract modifier in a trait in two cases?
I am studying the chapter on trait in the online book Programming In Scala 1ed.
There are two examples that demonstrate the power of features that enrich a thin interface and change across the stack. Here is an implementation snippet
// 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) }
}
The above code is fine for compilation.
I'm curious about the existence of the modifier abstract
, so I first added the modifier a abstract
before Relation::compare()
in Example 1. It might be wise to mark the abstract
before compare
that the subclass is about to override.
// case 1
abstract def compare(that: T): Int
Then the compiler complains
Error:(19, 16) `abstract' modifier can be used only for classes; it should be omitted for abstract members
abstract def compare(that: T): Int
^
I think this post says that it shouldn't put the modifier abstract
in a dash. So I am trying to remove the modifier abstract
from Doubling :: put in example 2 just like this
// case 2
override def put(a: Int) { super.put(a*2) }
But the compiler also complains
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) }
^
I know the reason for the modifier override
here, but I don't know why the compiler is complaining that I have to add the modifier with it abstract
. Is the compiler in the previous case just complaining that I should only put the abstract in the classes?
source to share
You say, "I think this message says he shouldn't put an abstract attribute on the line." No, this means that in Scala you mark an abstract class if it has abstract methods, but don't use the keyword abstract
for the methods themselves. The compiler knows that a method is abstract simply because you have not provided an implementation.
As in the second question, the reason you need the keyword abstract
when overriding put
is because it IntQueue
put
is abstract. You are telling the compiler that it super.put(a*2)
is not really an attempt to call an abstract method, which of course will not work - you are expecting a confusion of the trait in which the implementation is provided.
More details here .
source to share