Reputation: 272
public class NewClass
{
public static class superclass
{
static void print()
{
System.out.println("print in superclass.");
}
}
public static class subclass extends superclass
{
static void print()
{
System.out.println("print in subclass.");
}
}
public static void main(String[] args)
{
superclass A = new superclass();
superclass B = new subclass(); //This line?
A.print();
B.print();
}
}
I came across this code while learning static binding from geeksforgeeks. I am unable to understand this particular line:
superclass B = new subclass();
Not sure how this works. Basically, are we creating an object of super class and invoking the subclass' constructor? That doesn't make much sense to me because I have always seen and am used to : A obj = new obj();
type object creation.
Upvotes: 3
Views: 2143
Reputation: 7290
While preparing my answer, I found that I had to use the words superclass and subclass in two different meanings. I'll rename the classes to be Thing
and Car
and use the words "superclass" and "subclass" for the general concepts.
public class NewClass
{
public static class Thing
{
static void print()
{
System.out.println("print in superclass.");
}
}
public static class Car extends Thing
{
static void print()
{
System.out.println("print in subclass.");
}
}
public static void main(String[] args)
{
Thing A = new Thing();
Thing B = new Car(); //This line?
A.print();
B.print();
}
}
An expression new Car()
always creates an instance of type Car
. Always. And the result is [a reference to] an instance of Car
.
Now, you can store [a reference to] an instance of Car
into a variable of any type that allows for Car
instances. And that is:
Car
-typed variable,Car
(and this matches a Thing B
declaration),Car
.So, what happens with the line of code
Thing B = new Car(); //This line?
It creates a new Car
instance, and therefore of course invokes the Car
constructor (*1) (*2). And then it stores a reference to this instance in the variable B
, which allows for all kinds of Thing
instances as long as they inherit from Thing
and thus support everything that is expected from a Thing
object.
And what happens at
B.print();
It calls the print()
method of the instance that's referenced by B
. And as that instance is a Car
instance, you get the Car.print()
results, not the Thing.print()
.
Some more remarks:
If Car
had some additional methods not found in Thing
(e.g. a drive()
method), the compiler wouldn't allow you to call them on B
, as not all Thing
objects have them, but only some specialized Thing
versions (i.e. the Car
ones).
And I recommend to get used to the Java naming conventions, e.g. that classnames always begin with an upper-case letter and variables with lower-case. Java guys are so much used to these conventions that we find it really confusing to read code that doesn't follow these rules.
(*1) In your case the constructor is not explicitly defined, but auto-generated by the Java compiler.
(*2) A subclass constructor always calls the constructor of its superclass, and so on up to the Object
constructor, to initialize all the aspects of the instance that the subclass inherits from its superclass.
Upvotes: 3