Results 1 to 13 of 13
Thread: Using generics with interfaces
- 02-08-2011, 03:04 AM #1
Member
- Join Date
- Jan 2011
- Posts
- 5
- Rep Power
- 0
Using generics with interfaces
I would like to be able to declare a class with a generic parameter that is guaranteed to implement a specific interface. If I could do it the way I wanted, the code would look like this:
As suspected, the compiler doesn't accept the syntax, though it seems to me that it could work conceptually. Is there some reason having to do with type erasure that this couldn't compile to a valid runtime object?Java Code:class MyClass<E implements MyInterface> { ... }
Or more to the point, is there some other way to do this? I've thought of using an adapter class like this:
But the problem is the interface i have in mind (Shape) is already defined in Java, and I want to be able to use existing implementations of it. If I interpose my own adapter class I won't have access to them in this parametrization.Java Code:class MyClass<E extends MyAdapter> {...}
Any workarounds? It would be a big boon to my program to be have a way to do this.
-
I think that this:
Java Code:class MyClass<E implements MyInterface> { ... }
should be this:
Java Code:class MyClass<E extends MyInterface> { ... }
for example,
Java Code:import java.util.ArrayList; import java.util.List; public class InterfaceFooTest { public static void main(String[] args) { String[] data = {"Fe", "Fi", "Fo", "Fum"}; GenericUseOfInterface<Derived> genericUOI = new GenericUseOfInterface<Derived>(); for (String datum : data) { genericUOI.add(new Derived(datum)); } genericUOI.doAll(); } } class Derived implements MyInterface { private String text; Derived(String text) { this.text = text; } public void myMethod() { System.out.println("Text: " + text); } } class GenericUseOfInterface <E extends MyInterface> { List<E> myList = new ArrayList<E>(); public void add(E e) { myList.add(e); } public void doAll() { for (E e : myList) { e.myMethod(); } } } interface MyInterface { void myMethod(); }Last edited by Fubarable; 02-08-2011 at 03:17 AM. Reason: posted an example
- 02-08-2011, 03:20 AM #3
Member
- Join Date
- Jan 2011
- Posts
- 5
- Rep Power
- 0
-
I think you don't understand what I'm saying. Even though Rectangle2D implements Shape, this will work. You can't implement an interface within a generic statement, you can only extend. Please test it with the way I describe and look at my example above. You'll then see your logical error.
Last edited by Fubarable; 02-08-2011 at 03:41 AM.
- 02-08-2011, 03:38 AM #5
Member
- Join Date
- Jan 2011
- Posts
- 5
- Rep Power
- 0
Excellent! Many thanks for taking the time to demonstrate with the example. (I don't remember seeing the example in your original reply- did you add it there afterwards? Sorry if I just plain missed it in the first go-round.)
Last edited by Shayke; 02-08-2011 at 03:41 AM.
-
- 02-08-2011, 03:42 AM #7
Senior Member
- Join Date
- Jan 2009
- Posts
- 671
- Rep Power
- 5
Fubarable is correct. When using generics in this fashion, you always use 'extends' even for interfaces. The following compiles and runs, doing what you would expect.
Java Code:public class junk<E extends stuff> { public static void main(String[] args) throws Exception { new junk<stuffDoer>(new stuffDoer()); } public junk(E theStuffDoer) { theStuffDoer.doStuff(); } } interface stuff { public void doStuff(); } class stuffDoer implements stuff { public void doStuff(){ System.out.println("I did stuff"); } }
- 02-08-2011, 04:43 PM #8
Member
- Join Date
- Jan 2011
- Posts
- 5
- Rep Power
- 0
Part 2
I see these examples work, but I'm stuck again trying to understand the general case. This is more a theoretical question at this point.
Suppose I want a generic parameter that is required to both extend a class in the usual sense and also implement an interface. So the code might look like:
Java Code:class MyClass<E extends BaseClass, BaseInterface> {...}
(That actually compiles but does not perform as desired- the compiler appears to regard MyClass as having two separate variables, one extending BaseClass, the other extending BaseInterface).
Is there any way to put both conditions on a single parameter? Once again, I can't work around the problem by making my own class to extend the parameter from, since in the most general case there might be an existing class I want to use that already extends BaseClass and implements BaseInterface.
Off the top of my head it's hard to come up with a really compelling example- maybe it's critical that I know all my parametrized classes implement Serializable in addition to extending a base class?
In any case, since it seems like it should be possible to do this, I'd like to know how or understand why it can't be done.
- 02-08-2011, 07:17 PM #9
Senior Member
- Join Date
- Jan 2009
- Posts
- 671
- Rep Power
- 5
Ok, I understand what' you're trying to do. Hopefully it makes sense why
Is exactly accomplished simply byJava Code:class MyClass<E extends BaseClass implements InterfaceA, InterfaceB>
You *can* specify multiple interface generics, and the proer syntax isJava Code:class MyClass<E extends BaseClass>
The following compiles and runs and does what you expect:Java Code:class MyClass<E extends InterfaceA & InterfaceB>
Java Code:public class junk<E extends stuff & morestuff> { public static void main(String[] args) throws Exception { new junk<stuffDoer>(new stuffDoer()); } public junk(E theStuffDoer) { theStuffDoer.doStuff(); } } interface morestuff { public void doMoreStuff(); } interface stuff { public void doStuff(); } class stuffDoer implements stuff, morestuff { public void doMoreStuff(){} public void doStuff(){ System.out.println("I did stuff"); } }
- 02-08-2011, 07:36 PM #10
- Join Date
- Sep 2008
- Location
- Voorschoten, the Netherlands
- Posts
- 11,406
- Blog Entries
- 7
- Rep Power
- 17
- 02-08-2011, 08:13 PM #11
Member
- Join Date
- Feb 2011
- Posts
- 4
- Rep Power
- 0
Thanks. The specific example I had in mind was more like:
Java Code:class MyClass<E extends BaseClass & InterfaceA & InterfaceB> {...}
But I've verified that this works as well.
Not that it matters, but it seems odd to have invented a new syntax for generics, when intuitively (to me anyway) the old syntax would have sufficed. What else could the following mean except what I wanted?
Java Code:class MyClass<E extends BaseClass implements InterfaceA, InterfaceB> {...}
(BTW, I am the original poster, but messed up my password & email on the original account. Long story... Just wanted to say thanks for the solution.)
- 02-08-2011, 10:18 PM #12
Last edited by j2me64; 02-08-2011 at 10:31 PM.
- 02-08-2011, 10:34 PM #13
Last edited by j2me64; 02-08-2011 at 10:46 PM.
Similar Threads
-
Interfaces
By computerquip in forum New To JavaReplies: 19Last Post: 09-08-2009, 04:58 PM -
Interfaces
By jon80 in forum New To JavaReplies: 2Last Post: 05-03-2008, 09:57 PM -
interfaces..
By sireesha in forum New To JavaReplies: 5Last Post: 01-16-2008, 05:52 PM -
Interfaces
By Kavana Krishnappa in forum New To JavaReplies: 7Last Post: 12-11-2007, 04:28 PM -
Interfaces
By imran_khan in forum New To JavaReplies: 5Last Post: 07-30-2007, 08:11 AM


LinkBack URL
About LinkBacks
Reply With Quote

Bookmarks