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:
- a
Car-typed variable,
- a variable declared with any superclass of
Car (and this matches a Thing B declaration),
- a variable declared with an interface type directly or indirectly implemented by
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.