2

I'm preparing to SCJP and looks like I don't understand class cast principles.

class Dog extends Animal

First way of creating Dog() instance- make instance of Animal and cast it to Dog(upcast):

Animal a = new Dog();
Dog d1 = (Dog)a;

VS

Second way of creating Dog() instance - make it directly:

Dog d2 = new Dog();

what is the difference between d1 and d2 objects this case?

James
  • 5,355
  • 2
  • 18
  • 30
sergionni
  • 13,290
  • 42
  • 132
  • 189

4 Answers4

3

After the cast of a to Dog, there's no difference between d1 and d2. The cast is potentially problematic. If a isn't actually a Dog, you'll get a ClassCastException at runtime. Therefore, you would be better off verifying the runtime type with instanceof:

Animal a = new Dog();
Dog d1 = null;
if(a instanceof Dog)
{
    d1 = (Dog)a;
}

The real issue is that if you need a Dog, declare the variable as a Dog, not an Animal. If you're operating on any type of Animal, use the base class.

The type of a variable only specifies what interface you want to use -- whether it's the interface provided by the base class, an implementation of some class, or an actual interface. The type of a variable does not dictate its runtime type.

Jonathon Faust
  • 12,396
  • 4
  • 50
  • 63
2
Animal a = new Dog();// a dog is created but it will be referred by reference of animal as dog is an animal
Dog d1 = (Dog)a;//now we know that this animal is Dog so we are casting it to dog.

Dog d2 = new Dog();// we are creating instance of dog which is referred by reference of Dog

what is the difference between d1 and d2 objects this case?

d1 and d2 are just reference to dog, both will eventually refer to an instance of Dog . there is no difference

Also See

jmj
  • 237,923
  • 42
  • 401
  • 438
  • i don't quite understand following moment:Animal is Parent of Dog, and I know it.In what case I need do: Animal a = new Dog().Why not to do directly: Dog d = new Dog().In other words,what cases I should treat child as specific narrow parent?thanks – sergionni Mar 02 '11 at 17:26
  • 1
    suppose today there is Dog who is animal , tomorrow there can be tiger who is animal , so we should always program in abstract context. – jmj Mar 02 '11 at 17:47
  • Ok,I see your point.Actually,I've seen opinion recently, that there are 4 OOP principles - abstraction is fourth. Thank you for help. – sergionni Mar 02 '11 at 18:01
  • You will get very good point of encapsulation in your design., also see [this](http://stackoverflow.com/questions/147468/why-should-the-interface-for-a-java-class-be-prefered) – jmj Mar 02 '11 at 18:03
2

The first way is polymorphic because Animal can be a dog, cat, elephant, etc... whereas the latter way is not. Otherwise, there is no much difference between the 2.

limc
  • 39,366
  • 20
  • 100
  • 145
  • Of course, a `Dog` could be a `GermanShepherdDog` (my favorite), a `Doberman`, or a hundred others. Obviously if you instantiate it yourself, you know what it is, but if you're accepting the object from elsewhere, you don't know or need to know its real type. – Jonathon Faust Mar 02 '11 at 17:24
  • @Jonathan ,what you want to say, that if I knew about Dog class,that I should create it directly: Dog d=new Dog().And what mean "accepting the object from elsewhere"? – sergionni Mar 02 '11 at 17:31
  • 1
    @sergionni - What if you have a method declared like `public void feedTheDog(Dog d) { }` or better yet `public void feedTheAnimal(Animal a) { }`? In either case, you don't necessarily know the runtime type of the variable passed to your method. You **want** to be able to treat objects as generically as possible, in many cases. Why write a method for each type of `Animal` if you can just accept the base class and handle all cases? – Jonathon Faust Mar 02 '11 at 17:34
  • @Jonathan ok, that's clear for me. And one more issue. Animal a = new Dog();Dog d1 = (Dog)a; Is it upcasting or it un-generalization of Animal type to Dog type, I mean declaration of that, we treat Animal as a Dog? – sergionni Mar 02 '11 at 17:42
  • @sergionni: When you cast an animal as a dog (`Dog d1 = (Dog)a;`), the right term is "downcasting", not "upcasting". Since Dog class extends Animal class, the Dog class is at the lower hierarchy than Animal class. Google "java downcasting upcasting" for more examples. – limc Mar 02 '11 at 18:55
1

There is no difference in instantiation between these snippets: in both cases you instantiate object of type Dog by using new Dog(). Actually, it's about difference between type of object (runtime type) and type of variable (static type).

But in the first case you assign a reference to that object to variable of type Animal, and then assign value of that variable to another variable of type Dog. This requires cast since variable of type Animal may contain references to objects of types other than Dog, but in your case it references object of type Dog, so that cast is successful.

In the second case you assign value of type Dog to variable of type Dog directly.

axtavt
  • 239,438
  • 41
  • 511
  • 482