Polymorphism with Virtual Method Invocation,Heterogeneous Collections and Polymorphic Arguments


Describing a Manager as is an Employee is not just a convenient way of describing the relationship between these two classes. Recall that the Manager has all the members, both attributes and methods, of the parent class Employee. This means that any operation that is legitimate on an Employee is also legitimate on a Manager. If the Employee has the method getDetails, then the Manager class does also.

It might seem unrealistic to create a Manager and assign deliberately the reference to it to a variable of type Employee. However, this is possible, and there are reasons why you might want to achieve this effect.

An object has only one form (the one that is given to it when constructed). However, a variable is polymorphic because it can refer to objects of different forms.

The Java programming language, like most object-oriented languages, actually permits you to refer to an object with a variable that is one of the parent class types. So you can say:

Employee e = new Manager(); //legal

Using the variable e as is, you can access only the parts of the object that are part of Employee; the Manager-specific parts are hidden. This is because as far as the compiler is concerned, e is an Employee, not a Manager. Therefore, the following is not permitted:

// Illegal attempt to assign Manager attribute

e.department = “Sales”;

// the variable is declared as an Employee type,

// even though the Manager object has that attribute

Virtual Method Invocation

Assume that the following scenario is true:

Employee e = new Employee();

Manager m = new Manager();

If you ask for e.getDetails() and m.getDetails(), you invoke different behaviors. The Employee object executes the version of getDetails() associated with the Employee class, and the Manager object executes the version of getDetails() associated with the Manager class.

What is less obvious is what happens if you have:

Employee e = new Manager();


or something similar, such as a general method argument or an item from a heterogeneous collection.

In fact, you get the behavior associated with the object to which the variable refers at runtime. The behavior is not determined by the compile time type of the variable. This is an aspect of polymorphism, and is an important feature of object-oriented languages. This behavior is often referred to as virtual method invocation.

In the previous example, the e.getDetails() method executed is from the object’s real type, a Manager. If you are a C++ programmer, there is an important distinction to be drawn between the Java programming language and C++. In C++, you get this behavior only if you mark the method as virtual in the source. In pure object-oriented languages, however, this is not normal. C++ does this to increase execution speed.

Heterogeneous Collections

You can create collections of objects that have a common class. Such collections are called homogeneous collections. For example:

MyDate[] dates = new MyDate[2];

dates[0] = new MyDate(22, 12, 1964);

dates[1] = new MyDate(22, 7, 1964);

The Java programming language has an Object class, so you can make collections of all kinds of elements because all classes extend class Object. These collections are called heterogeneous collections.

A heterogeneous collection is a collection of dissimilar items. In object-oriented languages, you can create collections of many items. All have a common ancestor class: the Object class. For example:

Employee [] staff = new Employee[1024];

staff[0] = new Manager();

staff[1] = new Employee();

staff[2] = new Engineer();

You can even write a sort method that puts the employees into age or salary order, regardless of whether some of these employees are managers.

Note – Every class is a subclass of Object, so you can use an array of Object as a container for any combination of objects. The only items that cannot be added to an array of Object are primitive variables. However, you can create objects from primitive data using wrapper classes.

Polymorphic Arguments

You can write methods that accept a generic object (in this case, the class Employee) and work properly on objects of any subclass of this object.

You might produce a method in an application class that takes an employee and compares it with a certain threshold salary to determine the tax liability of that employee. Using the polymorphic features you can do this as follows:

public class TaxService {

public TaxRate findTaxRate(Employee e) {

// do calculations and return a tax rate for e



// Meanwhile, elsewhere in the application class

TaxService taxSvc = new TaxService();

Manager m = new Manager();

TaxRate t = taxSvc.findTaxRate(m);

This is legal because a Manager is an Employee. However, the findTaxRate method only has access to the members (both variables and methods) that are defined in the Employee class.