A Quick Tutorial on Casting

Recently, I’ve been teaching a class and one of the students stopped by after the class and said, “I’m just learning object-oriented programming, can you explain me the benefits of casting?”. How would you answer such a question? I did my best in a short period of time I had, but felt obligated to give better explanations and wrote this blog. I’ve been using example from Java language here, but all this apply to other object-oriented languages too.

All Java classes form an inheritance tree with the class Object on top of the hierarchy – all Java classes are direct or indirect descendants of Object. When you declare a non-primitive variable, you are allowed to use either the exact data type of this variable or one of its ancestor data types. For example, if the class NJTax extends Tax each of the following lines is correct.

NJTax myTax1 = new NJTax();
Tax myTax2 = new NJTax(); // upcasting
Object myTax3 = new NJTax(); // upcasting

Java is smart enough to automatically cast an instance of the class to its ancestor. When the variable has more generic class than an instance of the object it’s called upcasting. Let’s say the class object has ten methods and class variables defined, the class Tax (it’s an implicit subclass of Object) adds five more methods and variables (total 15), and NJTax adds another two (total 17). The variable myTax1 will have access to all 17 methods and variables, myTax2 will see only 15, and myTax3 just 10. Why not always use exact types in variable declarations?

Let’s say you need to write a program that will process the data about workers of a certain company. Some of them are full time employees, and some are contractors, but you’d like to read them from some data source and into the same array. Arrays can store only the objects of the same type, remember?

Since Java can automatically upcast the objects, you can create a class Person with two subclasses: Employee and Contractor, and then read the records from a database, and based on the employment type, create an appropriate object instance and put it into an array of type Person:

Person workers[] = new Person [100];
workers[0] = new Employee(“Yakov”, “Fain”);
workers[1] = new Employee(“Mary”, “Lou”);
workers[2] = new Contractor(“Bill”, “Shaw”);

Of course, you could’ve created two separate arrays for employees and contractors, but I’m laying the foundation here for explaining polymorphism – a powerful concept of object-oriented languages.

At some point you’ll need to process the data from the array workers. Say, in a loop you can test the data type of the current element of the array with the operator instanceOf, then downcast the object (it can’t be done automatically) to Employee or Contractor, and process it accordingly.

for (int i; i<20; i++){
Employee currentEmployee;
Contractor currentContractor;

if (worksers[i] instanceof Employee){
currentEmployee = (Employee) workers[i];
// do some employee processing here
} else if (worksers[i] instanceof Contractor){
currentContractor = (Contractor) workers[i];
// do some contractor processing here

Placing a data type in parenthesis in front of another object means that you want to downcast this object to specified type. You can downcast an object only to one of its descendant data types. Even though the above code has correct syntax, it doesn’t represent the best practice of processing similar objects. In the next lesson you’ll see how to use polymorphism to do it in a more generic way.
If a class implements an interface, you can cast it to this interface. Say, a class Employee implements Payable, Insurable, Pensionable interfaces:

class Employee implements Payable, Insurable, and Pensionable {
// implementation of all interfaces goes here

If in particular code you are interested in its Insurable behavior, there’s not need to cast the Object to type Employee, just cast it to Insurable type as shown in the code fragment below. Keep in mind though that if you do so, the variable current employee will expose the access to only those methods that were declared in the Insurable interface.

Insurable currentEmployee;

if (worksers[i] instanceof Employee Insurable){
currentEmployee = (Insurable) workers[i];
// do some insurance-specific processing here

Is it clear enough? I’d appreciate your feedback.

Yakov Fain

11 thoughts on “A Quick Tutorial on Casting

  1. Just a couple of comments:

    First: in your last example if you are looking for the Insurable interface, you could just plainly use

    if (workers[i] instanceof Insurable) { ….

    because otherwise you’ll lose all other instances of classes which implement Insurable. It’s much more interesting to work with interfaces anyway (many more pros than cons wrt using classes for type checking and type-dependant data process).

    OTOS, in the main cycle (for (int i; i<20; i++) { ), it's a mistake not to initialize the counter, even if all the implementations of the JVM automatically initialize integers to 0. Being that this post is aimed to novel programmers, I think it's worth to keep an eye over this kind of "guru"-style programming, which can lead juniors to make big mistakes.

    Best regards and thanks for all the interesting content you post.

  2. Sir, that is clear. We need to cast when we are assigning a super type to a sub type. We are more likely to use casting when working with the non-generic Java Collections Framework or passing parameters to a method call IMHO :)

  3. It’s quite simple, isn’t it?
    I think Bjarne Stroustrup has already wrtitten enough about it.

  4. @Saverio Agree, if (workers[i] instanceof Insurable) can make it a little cleaner. I was implying that only Employee can be Insurable :)

    @Ron casting is used in lots of situations that implement polymorphic behavior.

    @rauch You may be surprised, but there are millions of software developers who never read anything by Stroustrup. But I hope that even those who did can use this blog as a refresher :)

  5. Just would like to notice that before Java 5 casting was a normal way you write your program. And since Java 5 casting means you didn’t design your classes properly. And thus, you should think twice before casting anything explicitly.

  6. @Mykola I guess, you mean generics, but what do you do if an array has to store instances of different types – Employee and Contractor?

    Can you offer a better solution if you need to populate an array with different instances and then process them in a uniform manner?

  7. @Yakov, I would add some method to the base class if it is appropriate (make sense), or else I would create Strategy hierarchy and would use it’s methods to process taxes or something.
    Of course there is can be the place in the code which has to go through different subtypes and create for example appropriate strategies or something, but the idea is to keep that place isolated and not mess it with the business logic.

  8. @Mykola My goal is to keep the code simple and use polymorphism that’s nicely supported in Java. I guess, I need to write a follow up blog showing such an example.

  9. Thats one of the best n simplest example i have ever read of typecasting. Hope to get more by u on such basic concepts Yakov.

  10. Yakov, your example has nothing to do with casting. It’s all about RTTI. You can do the same with JavaScript or Python without *casting*

  11. @Yakov yes sir. type casting is used in lots of situations to implement polymorphic (one name, many forms) behavior with respect to references type (like what you already said). thanks for refreshing us about the essence of OOP using casting ^_^

Comments are closed.