-
Enhancement
-
Resolution: Not an Issue
-
P5
-
None
-
5.0
-
x86
-
linux
A DESCRIPTION OF THE REQUEST :
In some recently encountered situations, I would have liked java to have an @Implement annotation for methods to indicate, that a method declaration is intended to implement an abstract method declaration in a superclass or a method declaration in an implemented interface. If a method tagged with @Implement doesn't do so, the compiler should report an error.
Currently one *can* tag a method implementing an abstract superclass method with the @Override tag and I will now state, why this practice is error-prone:
Consider the case when you're writing some classes against an API that contains a class A with an abstract method m1. You extend this class with a concrete class and hence, you implement m1 and tag it with @Override. Since m1 is abstract, you don't have to think about calling super.m1() in your implementation of m1. The java compiler compiles your classes without warnings. Now the API undergoes some changes with one of them being m1 now getting a concrete implementation in A. If you upgrade to the new API, you're code will still compile with any warnings since you are now indeed overriding method A.m1. However, since A.m1 is now concrete, you should think about calling super.m1() in your version of m1. But normally, you won't even notice the crucial change in the API.
If your implementation of m1 would have been tagged with @Implement, the compiler would have reported an error, telling you that you can't implement a concrete superclass method and thus prevented you from the bad situation described above.
In one go, since it directly coheres, I'd like to propose a change of the terminus "override" in the Java Language Specification. Currently it is defined as follows:
An instance method in a subclass with the same signature (name,
plus the number and the type of its parameters) and return type
as an instance method in the superclass overrides the superclass's
method.
This includes the implementation of an abstract superclass method, which is, at least according to my intuition, no overriding. Overriding a method means to me to change a behaviour by providing a new version of the method. Implementing an abstract superclass method does not fit into that understanding, because you do not change a behaviour -- you introduce it. Hence, I would change the definition above to
An instance method in a subclass with the same signature (name,
plus the number and the type of its parameters) and return type
as an NON-ABSTRACT instance method in the superclass overrides
the superclass's method.
P.S.: I think having the same annotation "Implement" for implementing an interface method and an abstract method might not be completely clean, but I see no drawback in this. If you do, one could think about two different annotations for both purposes.
JUSTIFICATION :
Because the current behaviour is error-prone, see description for further details.
In some recently encountered situations, I would have liked java to have an @Implement annotation for methods to indicate, that a method declaration is intended to implement an abstract method declaration in a superclass or a method declaration in an implemented interface. If a method tagged with @Implement doesn't do so, the compiler should report an error.
Currently one *can* tag a method implementing an abstract superclass method with the @Override tag and I will now state, why this practice is error-prone:
Consider the case when you're writing some classes against an API that contains a class A with an abstract method m1. You extend this class with a concrete class and hence, you implement m1 and tag it with @Override. Since m1 is abstract, you don't have to think about calling super.m1() in your implementation of m1. The java compiler compiles your classes without warnings. Now the API undergoes some changes with one of them being m1 now getting a concrete implementation in A. If you upgrade to the new API, you're code will still compile with any warnings since you are now indeed overriding method A.m1. However, since A.m1 is now concrete, you should think about calling super.m1() in your version of m1. But normally, you won't even notice the crucial change in the API.
If your implementation of m1 would have been tagged with @Implement, the compiler would have reported an error, telling you that you can't implement a concrete superclass method and thus prevented you from the bad situation described above.
In one go, since it directly coheres, I'd like to propose a change of the terminus "override" in the Java Language Specification. Currently it is defined as follows:
An instance method in a subclass with the same signature (name,
plus the number and the type of its parameters) and return type
as an instance method in the superclass overrides the superclass's
method.
This includes the implementation of an abstract superclass method, which is, at least according to my intuition, no overriding. Overriding a method means to me to change a behaviour by providing a new version of the method. Implementing an abstract superclass method does not fit into that understanding, because you do not change a behaviour -- you introduce it. Hence, I would change the definition above to
An instance method in a subclass with the same signature (name,
plus the number and the type of its parameters) and return type
as an NON-ABSTRACT instance method in the superclass overrides
the superclass's method.
P.S.: I think having the same annotation "Implement" for implementing an interface method and an abstract method might not be completely clean, but I see no drawback in this. If you do, one could think about two different annotations for both purposes.
JUSTIFICATION :
Because the current behaviour is error-prone, see description for further details.
- relates to
-
JDK-6424261 Description of "override" in JLS 3 section 6.4.3 is misleading.
- Closed