Question

Let's say SList is a super class of TailList.

If I execute the following codes,

SList s;
TailList t = new TailList();
s = t;

is this same as doing SList s = new TailList();?

Now, is static type of t still TailList?

Was it helpful?

Solution

When you execute SList s = new TailList();, what happens is the following:

  1. new TailList() is invoked, creating a new object which the constructor of TailList is run for. When the constructor finishes, an anonymous TailList reference is returned.
  2. The anonymous TailList reference is assigned to s.

Since a TailList is inheriting from SList, you can also refer to it by that. The reference to the object doesn't change the object itself.

Imagine I put a trash bin somewhere, and then tell someone who doesn't know of that object being a trash bin that I put a "container" at that location. The trash bin is indeed a container, but that person only knows that it's a container. This doesn't change the fact that it's a trash bin, but the other person can't safely assume that he can put trash in there, or that it is scheduled to be emptied at any time, therefore he wouldn't know to invoke this functionality on the "container" that he is refering to.

So for instance, let's say we have the following code:

String s = "Hello there";
Object o = s;

o is now refering to a String object, but is treating it as an "object", it doesn't know that it has a length, or that it contains characters, even though it does.

s on the other hand, while still refering to the same object that o is refering to, knows that this object is a String, and can use String functionality on that object.

If we wanted to, we could assume that o is a String by a mechanism called "casting":

String s2 = (String)o;

We now refer to the object referenced by o as a String. All of this changes nothing for the object itself, it's all a mere change in reference. As if, for the previous analogy, the person who was told about the mysterious "container", will assume that the container is more specifically a "trash bin". We could also make a wrong assumption, that the container is a packaging container

Integer i = (Integer)o; // throws ClassCastException

Fortunately, when we assume wrongly in Java, we get a ClassCastException, unlike in real life where if you put your items into a trash bin while refering to it as a packaging container your belongings will be thrown to garbage.

Or perhaps, what is confusing you is that first assignment. Well, new TailList() part of SList s = new TailList(); by itself is a static invocation of the constructor of TailList, and it will always return a TailList reference. The assignment that comes afterwards will still refer to the TailList object that was constructed by the invocation.


TL;DR

Yes, it's the same thing.

OTHER TIPS

The object will be instantiated as TailList, and the assignment won't change that. (It would be a neat trick if the language could change the implementation class on assignment ;) )

For example, you can always go

TailList t = new TailList();
Object o = t;

Does that make it more clear? The object is still the same implementation class. It' not going to change to an Object, even though we're referencing it that way.

You could always do a System.err.println(s.getClass().getName()) and see.

BTW this is actually polymorphism rather than inheritance, because you're referencing the object as a class higher in the hierarchy. Inheritance would be if you called t.slistMethod() without overriding it.

In statically typed object-oriented languages, both objects and variables have an associated type.

The type of a variable (the 'static type') is specified by the programmer when declaring the variable. It never changes.

The type of the object referenced by the variable (the 'runtime type') must be either the same or a subtype of the variable's declared type. An object never changes type, but the variable may be assigned a different object of a different type.

The first snippet declares two variables, s of type SList and t of type TailList. It creates an object of type TailList and stores a reference to it in both variables.

The second snippet declares a variable s of type SList, creates an object of type TailList, and stores a reference to it in s.

The end result in both cases is that s contains a reference to an object of type TailList. The difference is that in the first snippet there is an additional reference to the object stored in variable t (which still has a static type of TailList).

Is

TailList t = new TailList();
SList s = t;

The same as

SList s = new TailList();

Yes, except there's no separate reference of type TailList held to the new object, so you'll only be able to access methods from SList (unless you cast).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top