0

I have a interface

public interface Doable<T,U> {
    public U doStuff(T t);
}

I have an abstract class which implements Doable<T,U>

public abstract class AbstractDoable<T,U> implements Doable<T, U> {
    private SomeClass someClass;

}

Now I need to implement the above classes, but I need to use different classes for T and U.

Please suggest how should I proceed in this as I will need to have multiple implemetations of AbstractDoable with different T and U. For example:

ConvertDoable<String,Integer> extends AbstractDoable

or

ConvertDoable<A,B> extends AbstractDoable
Mark Elliot
  • 75,278
  • 22
  • 140
  • 160
Ganesh
  • 1,654
  • 2
  • 19
  • 32
  • Can I have like this
    public class ConvertDoable extends AbstractDoable {}
    – Ganesh Jun 28 '11 at 06:02
  • @Gansu: No you can't. Both String and Integer are `final` classes – Bohemian Jun 28 '11 at 06:06
  • 1
    @Gansu: Yes, that should work. – Cameron Skinner Jun 28 '11 at 06:07
  • 1
    @Bohemian: That doesn't stop you declaring a generic type using the `extends` notation - it's just kinda meaningless in the case of final classes. You might get a compiler warning, but I'd be surprised if it was an error. That said, I haven't tried it myself so I'm happy to be proved wrong. – Cameron Skinner Jun 28 '11 at 06:08
  • @Bohemian, @Cameron ... I will not be using any final classes and that was an example. Please consider `Class1` and `Class2` instead of `String` and `Integer`. But I understand that final classes cannot be used here... thanks for bringing that in – Ganesh Jun 28 '11 at 06:28
  • @Gansu: Final classes *can* be used here. The whole point of generics is that you can use *any* class that meets the type bounds. – Cameron Skinner Jun 28 '11 at 06:33

5 Answers5

2

You can create whatever subclasses of Doable or AbstractDoable you want. For example:

public class DoNothing implements Doable<String, String> {
    public String doStuff(String input) {
        return input;
    }
}

or

public class DoSomething extends AbstractDoable<Integer, String> {
    public String doStuff(Integer i) {
        return i.toString();
    }
}

I'm not sure what the purpose of your someClass member is in AbstractDoable. Can you explain what it is for?

Cameron Skinner
  • 51,692
  • 2
  • 65
  • 86
1

If you're worried about class bloat, consider anonymous classes - classes defined "on the fly" as you need them:

public static void main(String[] args) {
    Doable<String, Integer> myDoable = new AbstractDoable<String, Integer>() {
        public Integer doStuff(String t) {
           return new Integer(t); // for example
        }
    }

    Integer i = myDoable.doStuff("0");
}
Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • I want it to be concrete...Not on the fly then my code would be in a controller and not in the actual implementation... – Ganesh Jun 28 '11 at 06:08
  • @Gansu: This is still concrete. There is a concrete implementation of `AbstractDoable` that just happens to be an anonymous inner class. – Cameron Skinner Jun 28 '11 at 06:10
1

Your concrete implementations should either specify the types on AbstractDoable

public class ConvertDoable extends AbstractDoable<String,Integer>
{
    public Integer doStuff(String arg){...}
}

or continue to pass along parameterized generics:

public class ConvertDoable<T,U> extends AbstractDoable<T,U>
{
    public U doStuff(T arg){...}
}
Mark Elliot
  • 75,278
  • 22
  • 140
  • 160
1
interface Doable<T,U> {
    public U doStuff(T t);
}

abstract class AbstractDoable<T,U> implements Doable<T, U> {
}

class ConvertDoableStringInteger extends AbstractDoable<String, Integer>{
    public Integer doStuff(String t) {
        return null;
    }   
}

class ConvertDoableIntergerFloat extends AbstractDoable<Integer, Float> {
    public Float doStuff(Integer t) {
        return 0.0f;
    }   
}
Petar Ivanov
  • 91,536
  • 11
  • 82
  • 95
0

The whole idea about generics is that you make a single class which supports all types of classes (or at least all classes who inherit from a class or implement an interface).

Also in Java (bytecode) there is no difference between say

GenericClass<A,B> foo;

and

GenericClass<C,D> bar;

You thus need to define a single class that can handle all the different objects that might be given to it.

dtech
  • 13,741
  • 11
  • 48
  • 73