Mark As Completed Discussion

Object Typecasting

Now let's learn another concept in OOP called typecasting. Typecasting, or type conversion, is the process of converting a primitive data type to another primitive data type. In the OOP world, we can only cast objects to compatible types. In most languages, typecasting is automatically preferred. For example, if we use a float as int or double, it will automatically typecast. See the example below:

1// This javascript code simulates the same scenario as your provided Java 
2// code snippet, whereby 2 floats f1 and f2 are passed and automatically 
3// converted to integers before performing addition
4let f1 = 0.5, f2 = 0.6;
5
6function add(i1, i2) {
7  return Math.floor(i1) + Math.floor(i2);
8}
9
10let i = add(f1, f2);
11console.log(i);

The type of conversion above is called automatic type conversion.

Other than the primitive types and built-in classes, user-defined interfaces or classes belonging to a single type hierarchy can be converted or cast into one another. However, if you attempt to convert objects with different types of hierarchy or different parent-child relationships, a compilation error will occur. At runtime, it is also possible to get a ClassCastException when you try to cast classes that are not in the same path in the class hierarchy.

In Java, if we set an object to one of its parents' reference types, then there is no way to call the parent object's methods that are overridden by the subclass. See the example below:

1class Shape {
2    draw() {
3        console.log("Only Draw Shape");
4    }
5}
6
7class Rectangle extends Shape {
8    draw() {
9        console.log("Drawing Rectangle");
10    }
11}
12
13// main.js
14let shape = new Rectangle();
15
16// This will always call overridden method
17shape.draw();
18// Output will be:
19// Drawing Rectangle

So how can we call a method of the Shape class? We can do this by first casting the Rectangle to Shape and then calling it.

1// main.js
2let shape = new Rectangle();
3
4// We cast the rectangle into Shape, and then call methods
5shape.draw();

Typecasting can be divided into two types:

  1. Upcasting: When you cast an object to one of its parent class types (i.e., from Rectangle to Shape).
  2. Downcasting: When you cast an object to one of its subtypes (i.e., from Shape to Rectangle)