9.17. Key Terms

 
[Page 313 ( continued )]

9.8. Casting Objects and the instanceof Operator

You have already used the casting operator to convert variables of one primitive type to another. Casting can also be used to convert an object of one class type to another within an inheritance hierarchy. In the preceding section, the statement

 m(   new   Student()); 

assigns the object new Student() to a parameter of the Object type. This statement is equivalent to

 Object o =   new   Student();  // Implicit casting  m(o); 

The statement Object o = new Student() , known as implicit casting , is legal because an instance of Student is automatically an instance of Object .

Suppose you want to assign the object reference o to a variable of the Student type using the following statement:

 Student b = o; 

A compilation error would occur. Why does the statement Object o = new Student() work and the statement Student b = o doesn't? Because a Student object is always an instance of Object , but an Object is not necessarily an instance of Student . Even though you can see that o is really a Student object, the compiler is not clever enough to know it. To tell the compiler that o is a Student object, use an explicit casting . The syntax is similar to the one used for casting among primitive data types. Enclose the target object type in parentheses and place it before the object to be cast, as follows :

 Student b =   (Student)   o; // Explicit casting 

It is always possible to cast an instance of a subclass to a variable of a superclass (known as upcasting ), because an instance of a subclass is always an instance of its superclass. When casting an instance of a superclass to a variable of its subclass (known as downcasting ), explicit casting must be used to confirm your intention to the compiler with the ( SubclassName ) cast notation. For the casting to be successful, you must make sure that the object to be cast is an instance of the subclass. If the superclass object is not an instance of the subclass, a runtime ClassCastException occurs. For example, if an object is not an instance of Student , it cannot be cast into a variable of Student . It is a good practice, therefore, to ensure that the object is an instance of another object before attempting a casting. This can be accomplished by using the instanceof operator. Consider the following code:


[Page 314]
  Object myObject =   new   Circle();  ...  // Some lines of code   /** Perform casting if myObject is an instance of Circle */    if   (myObject   instanceof   Circle) {   System.out.println(   "The circle diameter is "   +  ((Circle)myObject)  .getDiameter());   ... } 

You may be wondering why casting is necessary. Variable myObject is declared Object . The declared type decides which method to match at compile time. Using myObject.getDiameter() would cause a compilation error because the Object class does not have the getDiameter method. The compiler cannot find a match for myObject.getDiameter() . It is necessary to cast myObject into the Circle type to tell the compiler that myObject is also an instance of Circle .

Why not declare myObject as a Circle type in the first place? To enable generic programming, it is a good practice to declare a variable with a supertype , which can accept a value of any subtype.

Note

instanceof is a Java keyword. Every letter in a Java keyword is in lowercase.


Tip

To help understand casting, you may also consider the analogy of fruit, apple, and orange, with the Fruit class as the superclass for Apple and Orange . An apple is a fruit, so you can always safely assign an instance of Apple to a variable for Fruit . However, a fruit is not necessarily an apple, so you have to use explicit casting to assign an instance of Fruit to a variable of Apple .


9.8.1. Example: Demonstrating Polymorphism and Casting

Listing 9.6 is an example that demonstrates polymorphism and casting. The program creates two objects (lines 7 “8), a circle and a rectangle, and invokes the displayObject method to display them (lines 11 “12). The displayObject method displays the area and diameter if the object is a circle (line 17), and the area if the object is a rectangle (line 23). Figure 9.5 shows the output of the program.

Figure 9.5. The program demonstrates polymorphism and casting.



[Page 315]
Listing 9.6. TestPolymorphismCasting.java
 1    package   chapter9;  2  3   public class   TestPolymorphismCasting {  4  /** Main method */  5   public static void   main(String[] args) {  6  // Declare and initialize two objects  7      Object object1 =   new   Circle(   1   );  8      Object object2 =   new   Rectangle(   1   ,   1   );  9 10  // Display circle and rectangle  11  displayObject(object1);  12  displayObject(object2);  13    } 14 15  /** A method for displaying an object */  16   public static void    displayObject(Object object)  { 17   if   (  object   instanceof   Circle  ) { 18        System.out.println(   "The circle area is "   + 19          ((Circle)object).getArea()); 20        System.out.println(   "The circle diameter is "   + 21          ((Circle)object).getDiameter()); 22      } 23   else if   (  object   instanceof   Rectangle  ) { 24        System.out.println(   "The rectangle area is "   + 25          ((Rectangle)object).getArea()); 26      } 27    } 28  } 

The displayObject(Object object) method is an example of generic programming. It can be invoked by passing any instance of Object .

The program uses implicit casting to assign a Circle object to object1 and a Rectangle object to object2 (lines 7 “8), and then invokes the displayObject method to display the information on these objects (lines 11 “12).

In the displayObject method (lines 16 “27), explicit casting is used to cast the object to Circle if the object is an instance of Circle , and the methods getArea and getDiameter are used to display the area and diameter of the circle.

Casting can only be done when the source object is an instance of the target class. The program uses the instanceof operator to ensure that the source object is an instance of the target class before performing a casting (line 17).

Explicit casting to Circle (lines 19, 21) and to Rectangle (line 25) is necessary because the getArea and getDiameter methods are not available in the Object class.

Caution

The object member access operator ( . ) precedes the casting operator. Use parentheses to ensure that casting is done before the . operator, as in

 ((Circle)object).getArea(); 


 


Introduction to Java Programming-Comprehensive Version
Introduction to Java Programming-Comprehensive Version (6th Edition)
ISBN: B000ONFLUM
EAN: N/A
Year: 2004
Pages: 503

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net