Inheritance and Generics with Abstract Data Types

In this article, I want to demonstrate a simple inheritance example that uses generics.  The abstract parent class is generic in the type, and it defines an abstract method that accepts as a method parameter the generic data type.

The generic data type used by the extending child in the implementation of the abstract method. This example is going to discuss the benefit of this approach.

Consider the following parent class:

public abstract class Parent<T> {
    protected abstract void process(T data);
}

Consider the following two child classes that extend the parent:

public class Child extends Parent<SomeClass> {
    @Override
    public void process(SomeClass data) {
        // Do stuff
    }
}
public class AnotherChild extends Parent<OtherClass> {
    @Override
    public void process(OtherClass data) {
        // Do stuff
    }
}

You can clearly see how this approach creates flexibility when multiple child classes require different data type parameters when implementing the abstract method. Because of the generic type setting in the abstract method, any data type can be passed to the child. This approach can be particularly useful when implementing a strategy design pattern.

Brainteaser: Overridable methods

Consider the following case of inheritance:

public class  Parent {
   public Parent()  {
	getValue();
   }
   public void getValue()  {

   }
}

public class  Child extends Parent {
   private final Integer integer;
   public Child()  {
	integer = new Integer(888);
   }

   @Override
   public void getValue()  {
	System.out.println(integer);
   }
}

Question: What would the following program print, why?

public class  Test {
   public static void main(String[] args)  {
	Child child = new Child();
	child.getValue();
   }
}

Lets assume that getValue() implementation in Child class was changed to:

@Override
public void getValue()  {
     System.out.println(integer.toString());
}

Question: What would the output of the Test class be now, why?