Tuesday, 30 May 2017

Tutorial 21: Generic Classes and the Wildcard Operator



In the last tutorial, we looked at generic classes, and we started by introducing the ArrayList. Please note that whatever we discuss pertaining the ArrayList also works, to a large extent, with the other classes in the Java collections framework.

So for this tutorial, we learn about the wildcard operator to build on what we learnt in the past tutorial.

Let’s say that we have two classes, Machine and Vehicle. Now, let’s say that Vehicle is a child class of the Machine class. So, what we will do is create an ArrayList for both the Machine and the Vehicle class and try to do some operations on them.

Here is the Machine class:

public class Machine {

}

Here is the Vehicle class:

public class Vehicle extends Machine {
            public static void main(String[] args) {
                        ArrayList<Machine> machines = new ArrayList<Machine>();
                        machines.add(“computer”);
                        machines.add(“jet fighter”);
                        machines.add(“motorcycle”);

                        ArrayList<Vehicle> vehicles = new ArrayList<Vehicle>();
                        vehicles.add(“Subaru”);
                        vehicles.add(“Maserati”);
                        vehicles.add(“Volvo”);
            }
}

Now, let us create a method to output the contents of the ArrayList machines.

public static void showContents (ArrayList<Machine> machines) {
            for (Machine content : machines) {
                        System.out.println(content);
}



Figure 1: Output of the above program that prints out the contents of the ArrayList machines.

Now, what if we also want to use the same method to print out the contents of ArrayList containing items of the class Vehicle, which is a subclass of the Machine class?

You might be tempted to just pass the name of the ArrayList containing items of the type Vehicle as a parameter of the above method. And this is where you will go wrong. Here’s why:

Notice that while Vehicle is a child class of Machine, this does not mean that an ArrayList of that contains items of the Vehicle class is a child class of an ArrayList that contains Machine objects. This is a very important point to remember, and if there is one thing you should remember after reading this tutorial, it is this point.

So, how do we use the public void showContents (ArrayList<Machine> machines) method defined above to output an ArrayList that contains any object? We use the wildcard operator. The wildcard operator is a question mark and here is how we use it:

public void showContents (ArrayList<?> items)

In the above method definition, we are telling Java that our method will take, as an argument, any ArrayList. Because we haven’t specified the type of object that the ArrayList holds, Java will return an Object. So, this means that the body of the method also needs some modifications as follows:

public void showContents (ArrayList<?> items) {
            for (Object item: items) {
                        System.out.println(item);
}


Figure 2: Using the wildcard operator to show that the method accepts every ArrayList


The above method, will therefore take any ArrayList and print out its contents onto the console.

However, what if we want the method to just print out items of the Machine class and its child classes? We can specify this as follows:

public void showContents (ArrayList<? extends Machine> items) {
            for (Machine item: items) {
                        System.out.println(item);
}


Figure 3: Specifying that the message only accepts child classes of the Machine class


Now, what if we want to specify that the method takes as its argument, ArrayLists containing items of the Vehicle class and all its parent classes?

public void showContents (ArrayList<? super Vehicle> items) {
            for (Object item: items) {
                        System.out.println(item);
} 
 



Figure 4: Specifying that the message only accepts parent classes of the Vehicle class.


In this tutorial, we have learnt about the three ways to use the wildcard operator on ArrayList. Remember that these principles apply, to a large extent, to other classes in the Java collections framework. I will also deal with the Java collections framework in another course.

If you have any comments or questions, please don’t hesitate to drop them in the comments section below and I will address them.

In the next tutorial, we are going to look at anonymous classes.

Until next time, take care.
 



  

No comments:

Post a Comment