Java – Extending base class containing abstract generic method in java

abstractgenericsjavajava-7

I am given a Base class like this:

 Class MyBase{

   public abstract <T> Student assign (T object);

 }

I am extending it like below:

 Class MyClass extends MyBase{

   @Override
   public abstract <T> Student assign (T object){

     Student stew = new Student();
     ......

   }
 }

My intended use is: the passed in object should be of type Teacher. Within the method I want to create a new Student which will get some values by invoking functions on Teacher. (For example, stew.setTeacherName = teacher.getName();) And then return Student to the caller.

Questions:
a) How do I get the intended behavior?
b) Whats the difference between declaring MyBase the current way vs. doing MyBase ?
c) I am interested in knowing the solution in case where I CAN change Base class and I CANNOT change the Base class.

Thanks in advance for your help. Also, if there are any useful resources/tutorials you can point me to that would be great. Thanks again.

Best Answer

You cannot guarantee that the object being passed in to MyClass's assign method is a Teacher, if MyBase is defined this way. If you are allowed to modify MyBase, do the following:

abstract class MyBase
{
   public abstract <T extends Teacher> Student assign (T object);
}

and extend it with your class:

class MyClass extends MyBase
{
   @Override
   public <T extends Teacher> Student assign (T object){

     Student stew = new Student();
     ......

   }
}

This will guarantee that the object being passed in is a Teacher, even if it's really an instance of a subclass of Teacher.

EDIT: Another way to modify MyBase. Make the generic parameter part of the class definition instead of the method definition.

abstract class MyBase<T extends Teacher>
{
   public abstract Student assign (T object);
}

class MyClass<T extends Teacher> extends MyBase<T>
{
   @Override
   public  Student  assign (T object)
   {
      Student stew = new Student();
      ......
   }
}

// Could also do this...
class MyClass2 extends MyBase<Teacher>
{
   @Override
   public  Student  assign (Teacher object)
   {
      Student stew = new Student();
      ......
   }
 }

Here's Oracle's Java Generics Tutorial.