Question

Say you have a Shape base class and various derived types: Circle, etc.

Is there ever any reason to upcast right there when making a new object, by writing this:

Shape s = new Circle();

instead of this:

Circle s = new Circle();

and are the s objects made by each of these two statements in any way different from each other?

Was it helpful?

Solution

Those two statements will produce the same object as far as the JVM is concerned. It's not uncommon to show that you only plan to use the object for the base class or interface. E.g. this is common:

List<String> list = new ArrayList<String>();

Although generally not a good idea, you can cast the Shape back into a Circle if you know for sure that it is one, e.g. with Shape s you can bring it back to a Circle c with:

if (s instanceof Circle) {
    Circle c = (Circle) s;
    // handle Circle case
}

OTHER TIPS

You can argue that your first example (i.e. Shape s = new Circle();) can have the same advantages as "coding to the interface" even though Shape might be an abstract or even a concrete base class. So for example, if you only ever use the methods defined on Shape and not those specific to Circle, then you can quite easily just change the implementation you are using to a Square for example just by changing one line of code, i.e. Shape s = new Square();.

The objects are the same in both of your examples, the reason why the first option can be considered better is more of a style thing. Coding to interfaces can make a code base more easily extensible and modifiable.

The object instantiated are exactly the same.

The consequences of an upcasting are:

  1. generalization while storing : all objects of different specialized type can be threated as the same interface and can be stored together into data structure. (Like pointed out by @WhiteFang34 : List < Shape>)
  2. generalization while accessing objects method: the client class can call Shape's method without knowing the real type (typically you can use a factory to create object that returns the common interface Shape, so the client class is unaware of the real type of the objects but only the Shape's interface methods are exposed)

In answer to your question, the two objects are the exact same. Both references could point at the same object:

Circle c = new Circle();
Shape s = c;

Coding to interfaces allows you to change the implementation class with minimum impact on your code. Say you have this:

Set<String> names = new HashSet<String>();         // using Set reference not HashSet
names.add("Frank");
names.add("John");
names.add("Larry");

for(String name: names) {
    System.out.println(name + " is in the team");
}

Now your requirements change and you want the names to be printed in alphabetic order i.e. use HashSet instead of TreeSet. Because you have coded to the interface and not used any methods specific to the HashSet class you only have to change one line :

Set<String> names = new TreeSet<String>();   // the only line of code that changes
names.add("Frank");
names.add("John");
names.add("Larry");

for(String name: names) {
    System.out.println(name + " is in the team");
}

Interfaces also allow you to use dependency injection. It allows you to use classes that may not even exist at the time you write your code.

http://en.wikipedia.org/wiki/Dependency_injection

No, the objects themselves are not different. Only what the compiler thinks he's seeing is different (e.g. which methods are available).

One reason to do a cast like this is to express how you like to treat the object (so that you can easily insert a different derived class instead).

I agree to what @WhiteFang34 says.

See this Coding to interfaces? This might help you.

Circle s = new Circle();
here object is refering to class Cricle

Shape s = new Circle(); here object it refering to interface

Both are same.

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