so there is this question whether it’s “good style” to always use override when implementing abstract members. The advantage is that the compiler will throw an error if you accidentally try to implement a member that doesn’t exist. The big disadvantage IMHO is that the name override is badly chosen here.
So I wonder what people think of using a different modifier for this, for example implement:
“implement” doesn’t seem any more clear to me, since every non-abstract def is implemented. In object oriented programming languages this is a very common usage for “override.”
But you can also override an abstract method with another abstract method, or override a concrete method with another concrete method. The implement keyword seems to only fit the case where a concrete method overrides an abstract one.
I agree with this proposal. We could experiment first with a @implement annotation maybe?
The problem I see with the status quo is not just that override is badly chosen, but that it can have unintended consequences: if the abstract method evolves and become non-abstract, then the compiler will not tell you that your implementation now overrides an already implemented method.
In summary, by writing override when implementing methods you get a compilation error if you implement a method that was not defined in the parent types, but you don’t get an error if you try to implement an already implemented method. By contrast, by omitting override you get an error if you try to implement an already implemented method, but you don’t get an error if you implement a method that was not defined in the parent types.
An implement keyword (or @implement annotation) would raise an error if you try to implement an already implemented method, and also if you implement a method that was not defined in the parent types.
This is precisely why I generally do not use override in this situation. I’ve always found the preference to use it there a bit mysterious, since it seems to cause more difficulty than benefit. (I don’t personally find the status quo to be a problem, probably for that reason.)
If you’re providing an implementation to a method which is omitted, and the library designer provides a concrete implementation, it’s generally the sort of think it’s good to be made aware of.
Now, it could be that there isn’t anything which you’d need to do, other than replace implements with override, but there could be subtle behavioral differences the rest of the class expects that would be a pain to track down, and getting a heads up that the method contract had changed could be quite useful.
I’d be happy with implements alongside override. I’d be less interested in removing override.
Too many keywords. Such a fine distinction is not worth remembering a new keyword. Certainly not in the same universe in which private[this] & protected[this] got the axe for adding meaningless distinction
Let’s agree that OO inheritance contracts are broken and get rid of override.
Either overriding a concrete definition is brittle and it should be final, or it should be marked open for anyone who cares to override it.
I don’t really care if I’m overriding a trivial definition of close(), for example, or that I’m implementing an interface that extends Closeable or Autocloseable, etc.
If I have to care, then the superclass should define a better interface with proper extension points, and tell me exactly what I must implement.
Warnings could be emitted in suspect cases (similar to the proposal for open classes), unless language.wildwest.
During refactoring and migration, the build tool can tell me if I accidentally changed overriding.
These are all ways in which library authors could do better, but it doesn’t help the library users that currently have a rock-and-hard-place choice around override.
I’ve long wanted to an alternative to override, as @julienrf summarised, but what @kai says about too many keywords is also right…
Would someone be up to creating a schematic of the different cases and how override/implements/override implement would behave? It would be helpful.
If you want to make sure your method implementation does not override another implementation, what about mixins? Or would this be limited to classes only, not traits?
trait A {
def name: String
}
trait B extends A {
implement def name: String = "Alice"
}
trait C extends A {
implement def name: String = "Bob"
}
class D extends B with C {
}
object D {
val d: D = new D
println([d.name](http://d.name))
}
If this is legal, then what is the point of the implement modifier?