CASTING OBJECTS


CONTENTS

1. Introduction
 
2. Example



1. INTRODUCTION

In lectures we have discussed the process of casting a data item of one type to another. For example given a data item floatX which is of type float we can cast this to become an integer as follows:

intX = (int) floatX;

(assuming the existence an identifier intX of type int). We can do the same with objects. Let us assume that we have:

  1. A class, ClassOne and that object1 is an instance of this class, and
  2. A class, ClassTwo and that object2 is an instance of this class.

we can cast object1 so that it become an instance of the class, ClassTwo and assign it to the reference object2, as follows:

object2 = (ClassTwo) object1;

This will only work because object2 is an instance of the ClassTwo which extends ClassOne, i.e. object2 "knows all about" ClassOne because it is also an instance of ClassOne. It will not work the other way round. This kind of casting is therefore sometimes referred to as a downcast.




2. EXAMPLE

In Table 1 a class hierarchy is presented comprising two classes, ClassOne and ClassTwo. The first contains a field numX, a constructor and an output method which are all inherited by the second. In addition the class ClassTwo has a field numY, and a overrides the super-class output method. Note that the super-class output method is still called using the super label.

// CLASS ONE
// Frans Coenen
// 9 March 2000
// Dept Computer Science, University of Liverpool

class ClassOne {    

    // ----------- FIELDS -----------
    
    protected float numX;
    
    // ----------- CONSTRUCTOR ----------

    public ClassOne(float value) {
    	numX = value;
	}
	 
    // ----------- METHODS ---------- 
    
    /* Output */
    
    public void output() {    
        System.out.print("numX = " + numX);
	}   	
    }
    
// CLASS TWO
// Frans Coenen
// 9 March 2000
// Dept Computer Science, University of Liverpool

class ClassTwo extends ClassOne {
		
    // ----------- FIELDS -----------
    
    private float numY=0;
    
    // ----------- CONSTRUCTOR ----------
	   
    public ClassTwo(float value1, float value2) {
    	super(value1);
	numY = value2;
	}
	 		
    // ----------- METHODS ----------   
    
    /* Output */
    
    public void output() {
    	super.output();
        System.out.println(", numY = " + numY);
	}    
    }

Table 1: Class hierarchy

With reference to the class hierarchy presented in Table 1 the application code in Table 2 performs the following:

  1. Creates an instance of the class ClassOne referenced by the reference variable object1.
  2. Creates an instance of the class ClassTwo referenced by the reference variable object2.
  3. Assigns the value of object2 to object1 so that both reference variable now point to the same object. Note that this is done by an assignment operator because object1 references a super-class of object2. (In much the same way that we can assign an "int" too a "long").
  4. Assigns using a cast the value of object1 (now a reference to an instance of ClassTwo to object2 (the reference to the instance of ClassTwo). (In much the same way that we can cast a "long" too an "int").
// CASTING APPLICATION
// Frans Coenen
// 9 March 2000
// Dept Computer Science, University of Liverpool

class CastingApp {

    // ------------------ METHODS ------------------------ 
    
    /* Main method */
    
    public static void main(String[] args) {
        
	// Create instance of ClassOne and ClassTwo
	
	ClassOne object1 = new ClassOne(12);
	ClassTwo object2 = new ClassTwo(8,4);
	
	// Output
	
	System.out.print("object1 (instance of ClassOne): ");
	object1.output();
	System.out.print("\nobject2 (instance of ClassTwo): ");
	object2.output();
	
	// cast object2 so that it becomes an instance of the super-class
	// ClassOne
	
	object1 = object2;
	System.out.println("Assign reference value held in object2 to " +
	    		"object1 (no need for a cast)");
	System.out.print("object1 (instance of ClassOne): ");
	object1.output();
	System.out.print("object2 (instance of ClassTwo): ");
	object2.output();
	
	// cast object1 back so that it becomes an instance of ClassTwo
	// again
	
	object2 = (ClassTwo) object1;
	System.out.println("Cast object1 so that it becomes an instance " +
			"of ClassTwo, referenced by\n" +
			"\t the reference variable object2");
	System.out.print("object1 (instance of ClassOne): ");
	object1.output();
	System.out.print("object2 (instance of ClassTwo): ");
	object2.output();
	}
    }

Table 2: Application class

WARNING: In the above example we could not successfully cast an instance of the super-class (ClassOne) to become an instance of the ClassTwo because instances of the first know nothing about the numY attribute associated with instance of the second.




Created and maintained by Frans Coenen. Last updated 04 December 2001