Generic Class Hierarchies

  • Generic classes can be part of a class hierarchy in just the same way as a non-generic class.

  • In a generic hierarchy, any type arguments needed by a generic superclass must be passed up the hierarchy by all subclasses.

Using a Generic Superclass

// A simple generic class hierarchy.
class Gen<T> {
T ob;
Gen(T o) 
{
ob = o;
}
// Return ob.
T getob() 
{
return ob;
}
}
// A subclass of Gen.
class Gen2<T> extends Gen<T> //extends the generic class with type parameter T which is //passed by subclass
{
 Gen2(T o)
{
super(o);
}
}
public class Simple
{
public static void main(String args[])
{
Gen2<Integer> num = new Gen2<Integer>(100);
System.out.println("value:"+num.getob());
}
}

Output:

value:100

  • A subclass is free to add its own type parameters, if needed.
// A simple generic class hierarchy.
class Gen<T>
 {
T ob;
Gen(T o) 
{
ob = o;
}
// Return ob.
T getob() 
{
return ob;
}
}
// A subclass of Gen that defines a second
// type parameter, called V.
class Gen2<T, V> extends Gen<T> 
{
 V ob2;
 Gen2(T o, V o2)
 {
 super(o);
 ob2 = o2;
 }
 V getob2() 
{
 return ob2;
 }
}
// Create an object of type Gen2.
public class Simple
 {
 public static void main(String args[])
 {
 // Create a Gen2 object for String and Integer.
 Gen2<String, Integer> x = new Gen2<String, Integer>("Value is: ", 99);
 System.out.print(x.getob());
 System.out.println(x.getob2());
 }
}

Output:

Value is: 99

A Generic Subclass

  • It is perfectly acceptable for a non-generic class to be the superclass of a generic subclass.
// A non-generic class can be the superclass
// of a generic subclass.
// A non-generic class.
class NonGen {
 int num;
 NonGen(int i) {
 num = i;
 }
 int getnum() {
 return num;
 }
}
// A generic subclass.
class Gen<T> extends NonGen {
 T ob; // declare an object of type T
 // Pass the constructor a reference to
 // an object of type T.
 Gen(T o, int i) {
 super(i);
 ob = o;
 }
 // Return ob.
 T getob() {
 return ob;
 }
}
// Create a Gen object.
public class Simple {
 public static void main(String args[]) {
 // Create a Gen object for String.
 Gen<String> w = new Gen<String>("Hello", 47);
 System.out.print(w.getob() + " ");
 System.out.println(w.getnum());
 }
}

Output:

Hello 47

Run-Time Type Comparisons Within a Generic Hierarchy

  • instanceof determines if an object is an instance of a class. It returns true if an object is of the specified type or can be cast to the specified type.
  • The instanceof operator can be applied to objects of generic classes.
// Use the instanceof operator with a generic class hierarchy.
class Gen<T> 
{
 T ob;
 Gen(T o) 
{
 ob = o;
 }
 // Return ob.
 T getob() 
{
 return ob;
 }
}

// A subclass of Gen.
class Gen2<T> extends Gen<T> 
{
 Gen2(T o) 
{
 super(o);
 }
}

// Demonstrate run-time type ID implications of generic
// class hierarchy.
public class Simple
 {
 public static void main(String args[]) 
{
 // Create a Gen object for Integers.
 Gen<Integer> iOb = new Gen<Integer>(88);

 // Create a Gen2 object for Integers.
 Gen2<Integer> iOb2 = new Gen2<Integer>(99);

// Create a Gen2 object for Strings.
 Gen2<String> strOb2 = new Gen2<String>("Generics Test");

// See if iOb2 is some form of Gen2.
 if(iOb2 instanceof Gen2<?>)
 System.out.println("iOb2 is instance of Gen2");

 // See if iOb2 is some form of Gen.
 if(iOb2 instanceof Gen<?>)
 System.out.println("iOb2 is instance of Gen");

 System.out.println();

 // See if strOb2 is a Gen2.
 if(strOb2 instanceof Gen2<?>)
 System.out.println("strOb2 is instance of Gen2");
 // See if strOb2 is a Gen.
 if(strOb2 instanceof Gen<?>)
 System.out.println("strOb2 is instance of Gen");

 System.out.println();

 // See if iOb is an instance of Gen2, which it is not.
 if(iOb instanceof Gen2<?>)
 System.out.println("iOb is instance of Gen2");
else
System.out.println("iOb not a instance of Gen2");

 // See if iOb is an instance of Gen, which it is.
 if(iOb instanceof Gen<?>)
 System.out.println("iOb is instance of Gen");

 // The following can't be compiled because
 // generic type info does not exist at run time.
// if(iOb2 instanceof Gen2<Integer>)
// System.out.println("iOb2 is instance of Gen2<Integer>");
 }
}

Output:

iOb2 is instance of Gen2

iOb2 is instance of Gen

strOb2 is instance of Gen2

strOb2 is instance of Gen

iOb not a instance of Gen2

iOb is instance of Gen

Casting

We can cast one instance of a generic class into another only if the two are

  • compatible
  • Type arguments are the same

    (Gen <Integer>) iOb2// legal because iOb2 includes an instance of Gen<Integer>

. But, this cast:(Gen <Long>) iOb2// illegal is not legal because iOb2 is not an instance of Gen<Long>

Overriding Methods in a Generic Class

  • A method in a generic class can be overridden just like any other method.
// Overriding a generic method in a generic class.
class Gen<T> 
{
 T ob; // declare an object of type T
 // Pass the constructor a reference to
 // an object of type T.
 Gen(T o)
 {
 ob = o;
 }
 // Return ob.
 T getob() 
{
 System.out.print("Gen's getob(): " );
 return ob;
 }
}

// A subclass of Gen that overrides getob().
class Gen2<T> extends Gen<T>
 {
 Gen2(T o) 
{
 super(o);
 }
 // Override getob().
 T getob()
 {
 System.out.print("Gen2's getob(): ");
 return ob;
 }
}
// Demonstrate generic method override.
public class Simple 
{
 public static void main(String args[]) 
{
 // Create a Gen object for Integers.
 Gen<Integer> iOb = new Gen<Integer>(88);

// Create a Gen2 object for Integers.
 Gen2<Integer> iOb2 = new Gen2<Integer>(99);

// Create a Gen2 object for Strings.
 Gen2<String> strOb2 = new Gen2<String> ("Generics Test");

System.out.println(iOb.getob());
 System.out.println(iOb2.getob());
 System.out.println(strOb2.getob());
 }
}

Output:

Gen's getob(): 88

Gen2's getob(): 99

Gen2's getob(): Generics Test

results matching ""

    No results matching ""