Java Reference
In-Depth Information
if(pet instanceof Duck)
((Duck)pet).layEgg(); // It is a duck so we can have an egg for tea
So what is the difference between this and using
getClass()
? Well, it's quite subtle. The
instanceof
operator checks whether a cast of the object referenced by the left operand to the type
specified by the right operand is legal. The result will be true if the object is the same type as the right
operand,
or of any subclass type
. We can illustrate the difference by choosing a slightly different example.
Suppose
pet
stores a reference to an object of type
Spaniel
. We want to call a method defined in the
Dog
class so we need to check that
pet
does really reference a
Dog
object. We can check for whether
or not we have a
Dog
object with the statements:
if(pet instanceof Dog)
System.out.println("We have a dog!");
else
System.out.println("It's definitely not a dog!");
We will get confirmation that we have a
Dog
object here even though it is actually a
Spaniel
object.
This is fine though for casting purposes. As long as the
Dog
class is in the class hierarchy for the object,
the cast will work OK, so the operator is telling us what we need to know. However, suppose we write:
if(pet.getClass() == Dog.class)
System.out.println("We have a dog!");
else
System.out.println("It's definitely not a dog!");
Here the
if
expression will be
false
because the class type of the object is
Spaniel
, so its
Class
object is different from that of
Dog.class
- we would have to write
Spaniel.class
to get the value
true
from the
if
expression.
We can conclude from this that for casting purposes you should always use the
instanceof
operator
to check the type of a reference. You only need to resort to checking the
Class
object corresponding to
a reference when you need to confirm the exact type of the reference.
Designing Classes
A basic problem in object-oriented programming is deciding how the classes in your program should
relate to one another. One possibility is to create a hierarchy of classes by deriving classes from a base
class that you have defined, and adding methods and data members to specialize the subclasses. Our
Animal
class and the subclasses derived from it are an example of this. Another possibility is to define
a set of classes which are not hierarchical, but which have data members that are themselves class
objects. A
Zoo
class might well have objects of types derived from
Animal
as members, for instance.
You can have class hierarchies that contain data members that are class objects - we already have this
with our classes derived from
Animal
since they have members of type
String
. The examples so far
have been relatively clear-cut as to which approach to choose, but it is not always so evident. Quite
often you will have a choice between defining your classes as a hierarchy, and defining classes that have
members that are class objects. Which is the best approach to take?