Reputation: 266978
I currently have the following method in a class which I hope I can push to a superclass since I will have a few other classes which will need similar functionality.
public long convertToLong(EnumSet<SomeTypeHere> es) {
long a = 0;
for(SomeTypeHere sth : es) {
a += sth.someLongProperty();
}
}
It would be great if I can do this, I've never really used java generics before other than with collections.
Upvotes: 3
Views: 90
Reputation: 1260
yep - java intersection types (Bohemian's answer) do what you want. I had a similar issue where I had a number of enum classes that I all wanted to have a getDescription() method.
In general, intersection types get around the issue that you can't subclass enums.
Upvotes: 0
Reputation: 424993
This code below does what you need. The key is the use of the generic syntax that bounds a type to multiple types - in this case an Enum and your interface.
This compiles:
public interface HasSomeLongProperty {
long someLongProperty();
}
public static enum Fruit implements HasSomeLongProperty {
apple(1),
orange() {
// You may override the default implementation and delegate
public long someLongProperty() {
// You could also make this a field and not new every call
new SomeHasSomeLongPropertyImpl().someLongProperty();
}
};
private long value;
private Fruit() {
}
private Fruit(long value) {
this.value = value;
}
public long someLongProperty() {
return value;
}
}
public static <T extends Enum<T> & HasSomeLongProperty> long convertToLong(EnumSet<T> es) {
long a = 0;
for (T sth : es)
a += sth.someLongProperty();
return a;
}
Upvotes: 2
Reputation: 30445
You will need to put a bound on the generic type. If the class which contains convertToLong
is parameterized on the same type, you can put the bound there:
import java.util.*;
public class GenericTest<C extends GenericTest.HasLongProperty> {
static interface HasLongProperty {
long someLongProperty();
}
public long convertToLong(Collection<C> es) {
long a = 0;
for(C sth : es)
a += sth.someLongProperty();
return a;
}
}
Or if the class which contains convertToLong
is not generic, you can put the bound in the declaration of that one method alone:
import java.util.*;
public class GenericTest {
static interface HasLongProperty {
long someLongProperty();
}
public <C extends GenericTest.HasLongProperty> long convertToLong(Collection<C> es) {
long a = 0;
for(C sth : es)
a += sth.someLongProperty();
return a;
}
}
Upvotes: 3
Reputation: 679
I think you want something like this:
public <T extends SomeType> long convertToLong(Collection<T> es) {
long a = 0;
for(T sth : es) {
a += sth.someLongProperty();
}
return a;
}
This says that you can pass in a Set of type T where T can be any subclass of SomeType and SomeType has the function someLongProperty.
Upvotes: 2