I have three classes
class WithInner {
class Inner {}
}
public class InheritInner extends WithInner.Inner
{ //constructor
InheritInner(WithInner wi) {
wi.super();
}
}
This example is taken from Eckel's Thinking in Java. I can't understand why we can't call wi = new WithInner();
instead of .super()? And while calling wi.super()
we are calling Object's default constructor, aren't we?
The super keyword in Java is a reference variable which is used to refer immediate parent class object. Whenever you create the instance of subclass, an instance of parent class is created implicitly which is referred by super reference variable.
First approach (Referencing using Superclass reference): A reference variable of a superclass can be used to a refer any subclass object derived from that superclass. If the methods are present in SuperClass, but overridden by SubClass, it will be the overridden method that will be executed.
In java, super keyword is used to access methods of the parent class while this is used to access methods of the current class. this keyword is a reserved keyword in java i.e, we can't use it as an identifier. It is used to refer current class's instance as well as static members.
Yes. If you call super() it will invoke the constructor of the super-class that takes no arguments.
Inner classes maintain a reference to an outer instance (the exception is static
inner classes). In this case, a WithInner.Inner
instance has a reference to the containing WithInner
instance. This association is created when the inner class is instantiated.
You cannot create an instance of the inner class without a reference to the outer class. A class that extends such an inner class also has by implication such a reference, and needs to delegate to the inner class constructor in order to set up the association. The syntax for doing that is as shown in your example:
wi.super();
Here, super()
essentially refers to the superclass constructor - that is, the WithInner.Inner
constructor. The constructor takes no parameters formally, but it still needs a reference to the outer instance (of type WithInner
). The line as a whole essentially means "call the superclass constructor, and associate with the wi
instance".
Compare to the syntax for instantiation of an inner class with explicit association:
wi.new WithInner.Inner()
Yes, that's also valid syntax. It's not commonly seen in the wild, though (because inner class instances are normally only created from within the outer class anyway, and in that case the association is implicit - there's no need in that case for this syntax, which provides the association explicitly).
With specific reference to your question:
I can't understand why we can't call wi = new WithInner(); instead of .super()?
This would not associate the created WithInner
instance with the inner class instance. You'd get a compile-time error because your InheritInner
constructor wouldn't any longer be explicitly calling the synthesized superclass constructor, and it can't be called implicitly because it needs the outer instance reference for association. It's probably easiest to think of the outer instance reference as a hidden parameter to the inner class constructor (indeed, that's how it's implemented under the hood).
And while calling wi.super() we are calling Object's default constructor, aren't we?
No, you're calling the WithInner.Inner
constructor, which has a "hidden" parameter for the outer instance reference; wi
is essentially passed to the WithInner.Inner
constructor as a hidden parameter value.
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