Page 1 of 1

Generics, static and dynamic types, polymorphism: an introduction Rate Topic: ***** 2 Votes

#1 Renagado  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 111
  • View blog
  • Posts: 388
  • Joined: 14-June 09

Posted 13 May 2011 - 08:47 AM

*
POPULAR

Generics, static and dynamic types, polymorphism: an introduction


Since I haven’t seen any tutorial on the subject of generics in the Java tutorials, I’ve decided to give a short explanation for it. This is not going to be covering the more advanced stuff, like creating your own generic classes etc, it will just focus on problems encountered by people beginning with programming. The language used here is Java, however the subject is common to most modern languages. Also this tutorial covers some aspects of static and dynamic typing, and one of the OOP(object oriented programming) pillars: polymorphism.

Alright, let’s begin!

A little history


Everybody who programs in any way knows we need to store data. To store it in memory you use variables, or when you need a lot, you use an array. However, as you probably know, arrays are the old school way of doing things, in the object oriented world we use classes like ArrayList, Stack, HashMap etc etc. Those provide a lot more functionality, at the cost of a bit more overhead. I’m assuming this is all known already. For the examples in this tutorial I’m using the ArrayList, since it’s probably the most used of all Collections, and the workings are similar for all. Up until Java 5 in 2004 there were only the non-generic types, and from Java 5 the generic types were finally added, to avoid the problems non-generic types gave(I will explain those in a moment).

Problem 1: everything is an object

Let’s consider a typical usage scenario of the (non-generic) ArrayList.
 ArrayList list = new ArrayList();//instantiating a new ArrayList
       list.add(new Integer(10));//add some integers
       list.add(new Integer(20));

Great, we’ve stored the integers. Now let’s do something with them:
 ArrayList list = new ArrayList();//instantiating a new ArrayList
       list.add(new Integer(10));//add some integers
       list.add(new Integer(20));
       for(Integer i: list)//error?what's this? there are integers here right?
       {
           System.out.println(i);
       }

Wait a second…we’re getting an error…now why is that? The reason for this is that everything you store in the ArrayList is stored as an Object. This is possible because everything…yes EVERYTHING in Java is an Object/inherits from Object. The only exceptions are the primitive types like int and bool etc, but those are well…"primitive". Look at the following example.
Object number = new Integer(10);//this is correct

In this case, we gave number the static type of Object. And the dynamic type of Integer. This is possible because Integer inherits from Object, so you can say a Integer IS A Object. For a proof look at the following bit of JavaDoc:

Attached Image

You can see here, Integer inherits from Number, which inherits from…Object.
Now with this bit of background we can understand what gave the error. All that is stored in the non-generic list has the static type of Object, no matter the dynamic type. But since the dynamic type still is Integer, there sure must be a way to tell Java the Object really is an Integer? Yes there is, it’s called casting:
      ArrayList list = new ArrayList();//instantiating a new ArrayList
       list.add(new Integer(10));//add some integers
       list.add(new Integer(20));
       for(Object o: list)//we agree now the static type is object
       {
           System.out.println((Integer)o);//the casting takes place here
       }

Problem solved! Great! But this is kind of messy right? We go from Integer to Object and back…Yuck.

Enter generics


Now with generics, we can make things so much easier and cleaner. By using an ArrayList<Integer> we make a "special" kind of ArrayList, one that doesn’t contain the static type Object, but the static type of Integer. That way, no casting is needed.
       ArrayList<Integer> genericList = new ArrayList<Integer>();//instantiating a new ArrayList
       genericList.add(new Integer(10));//add some integers
       genericList.add(new Integer(20));
       for(Integer i: genericList)//great! it works now, and much cleaner too
       {
           System.out.println(i);
       }

Now if you think about it, this doesn’t mean you can only store the object type you specify, in an inheritance tree you can also store the children of the class you specified. It only means you can’t go downwards to Object. So you're basically limiting the possibilities. Which is great, because this allows polymorphism(will cover that later).

Note: Java 7 will support this syntax for construction: ArrayList<Integer> genericList = new ArrayList<>();

Problem 2: type mixing


One of the "features" of non-generic types is that you can store everything in them. So it’s a store all box, like the ones in the garage. Sounds good, sounds handy. But it isn’t. Why? Because it’s error prone. Look at this(simple) example.
      ArrayList list = new ArrayList();//instantiating a new ArrayList
       list.add(new Integer(10));//add some things
       list.add("hello world!");
       list.add(new Integer(20));
       for(Object o: list)//Great, no compiling errors, the IDE is happy
       {
           System.out.println((Integer)o);//the casting takes place here
       }

When running this…BOOM…exception. Makes sense. Why tried to mold a String into an Integer. And ofcourse we can test for the dynamic type using the instanceof operator:
      ArrayList list = new ArrayList();//instantiating a new ArrayList
       list.add(new Integer(10));//add some things
       list.add("hello world!");
       list.add(new Integer(20));
       for(Object o: list)//Great, no compiling errors, the IDE is happy
       {
           if(o instanceof Integer)
           System.out.println((Integer)o);//the casting takes place here
       }

Now the program skips the String, and everybody is happy. You can see how generics solve this problem. Still it looks like lost functionality, since we’re constraining ourselves to Integers. Well its not. Of course in this simple example its easy enough to spot the problem, but when programs get bigger it’s not! Just don’t do it, it’s a BIG NO. Occasionally you want to store different things in the same list, but then you do it in another way: polymorphism.

Problem 3: difficult polymorphism

Poly…what? Literally it means many forms, and it’s one of the pillars of OOP programming. Since this isn’t an intro to OOP I’ll just touch this subject lightly. Let’s say we have this simple class structure:
abstract class Animal
{
    public abstract String makeSound();
}

class Dog extends Animal
{
    @Override
    public String makeSound()
    {
        return "Woof!";
    }
}
class Cat extends Animal
{
    @Override
    public String makeSound()
    {
        return "Meow!";
    }   
    public void coughUpHairBall()
    {
        //a cat specific thing
    }
}

Here we have one abstract base class called Animal, and two classes, Dog and Cat, implementing the abstract method makeSound(). Say this was a game, and we have like a list of the NPC’s in memory, like this:
        ArrayList<Animal> animals = new ArrayList<Animal>();
        animals.add(new Dog());
        animals.add(new Cat());
        for(Animal a: animals)
        {
            System.out.println(a.makeSound());
        }

Now that’s polymorphism in action! Since the static type of both Cat and Dog is Animal(a cat IS A animal) and since all Animals must implement the makeSound() method, we don’t have to worry about the dynamic type no more. That is unless we want to use cat or dog specific thing, then we need to resolve to casting and type checking as I mentioned before. But you can see the big gain here when using generics I hope!

Conclusion

I hope this sheds some light on the subject of Generics, and why they are useful. Also the difference between static and dynamic type is a very common cause for confusion amongst beginners in an OOP language, so I hope this tutorial will help with that too. Before I’m gone, I just wanted to mention I wrote this tutorial for fun, but feedback is always welcome!

This post has been edited by Renagado: 14 May 2011 - 04:07 AM


Is This A Good Question/Topic? 11
  • +

Replies To: Generics, static and dynamic types, polymorphism: an introduction

#2 Niha  Icon User is offline

  • New D.I.C Head

Reputation: 4
  • View blog
  • Posts: 42
  • Joined: 20-April 07

Posted 22 June 2011 - 07:09 AM

Thanks. I've finally understood the difference between the two types of definition for ArrayList. we weren't even taught ArrayList in high school Java, just arrays
Was This Post Helpful? 0
  • +
  • -

#3 EmberZ  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 01-January 12

Posted 01 January 2012 - 08:06 AM

This was very helpfull! Thanks very much.
Was This Post Helpful? 0
  • +
  • -

#4 JavaT  Icon User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 60
  • Joined: 21-February 11

Posted 11 January 2012 - 12:04 PM

Easy to understand. Good job.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1