Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use super() with reference in Java

Tags:

java

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?

like image 999
Dmitry Pekach Avatar asked Mar 04 '16 10:03

Dmitry Pekach


People also ask

What is super reference in Java?

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.

How do you reference a super class variable in Java?

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.

What is the role of super () and this () in Java?

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.

Can we pass parameter to super keyword in Java?

Yes. If you call super() it will invoke the constructor of the super-class that takes no arguments.


1 Answers

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.

like image 53
davmac Avatar answered Nov 02 '22 09:11

davmac