Consider the following class:
public abstract class AbstractClass {
public abstract String m();
public AbstractClass get(){
return new AbstractClass() {
@Override
public String m() {
return "Anonymous " + super.m(); //1, Compile-time erro
}
};
}
}
It's not clear why such using of super
is prohibited. At //1
, the following error is occured
Cannot directly invoke the abstract method m() for the type AbstractClass
So, I consulted the JLS 15.11.2 and didn't find the restriction preventing such code from being compiled. Here they are:
It is a compile-time error if the forms using the keyword super appear in the declaration of class Object, since Object has no superclass.
AbstractClass
, but only one of its concrete subclasses, the following seems to me valid as well:The forms using the keyword super are valid only in an instance method, instance initializer, or constructor, or in the initializer of an instance variable of a class. If they appear anywhere else, a compile-time error occurs.
It is a compile-time error if the current class is not an inner class of class T or T itself.
Of course, I can use AbstractClass.this.m()
, but this is not what I'm asking about.
The super keyword does not work here because AbstractClass. m() has been declared abstract, and therefore there is no suitable implementation of it on the parent of the inner class. Remember that inner classes do not extend the outer class (even if it is of the same type), they include a reference to it instead.
An abstract superclass is one way to provide re-usable code. You can extend the abstract class and inherit the code. This is sometimes more convenient than using static methods or object composition to share code. The abstract class can "fix" parts of the code (by making it final).
An abstract class serves as a basis (that is, a superclass) for a group of related subclasses. An abstract class can define abstract properties and methods that subclasses implement. Each subclass can implement the concrete properties and methods in a way that supports their specific requirements.
If a class is defined with the keyword abstract, we may call its constructor only via super in a class that extends it, not via the new operator. That is, we cannot explicitly construct an object using an abstract class, but we can use it to help construct an object from a subclass.
The super keyword does not work here because AbstractClass.m()
has been declared abstract, and therefore there is no suitable implementation of it on the parent of the inner class. Remember that inner classes do not extend the outer class (even if it is of the same type), they include a reference to it instead.
However when working from an inner class calling to the outer class (which is what I believe you meant to do here) then use the following syntax AbstractClass.this.m()
.
The following will compile and work as intended.
public abstract class AbstractClass {
public abstract String m();
public AbstractClass get(){
return new AbstractClass() {
@Override
public String m() {
return "Anonymous " + AbstractClass.this.m();
}
};
}
}
As far as i know, the compiler tries to use static binding when using super.m();
. As there is no method super.m();
since it is abstract the compiler already complains at compile time.
Static binding in Java means that the methods are resolved during compile time while dynamic binding occurs during runtime when using a method which could be override by several subclasses.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With