How can I create abstract generic method doSomething() that accepts different enums? Enum1 and Enum2, Enum3 and so on?
public abstract class NumerOne {
public abstract void doSomething();
}
public class NumberTwo extends NumberOne {
#Override
public void doSomething (Enum1 enum1) {
enum1.createSomething();
}
The most appropriate way to accept a handful of Enum types, but not accept any enum (<T extends Enum<T>) or (even worse) Object would be to create an interface and have all the enums that you want to accept implement that interface:
interface CreatorOfSomething {
// I have no idea what type should be returned here,
// as you don't use this value in your example.
// But I'm pretty sure it can't be void, so I'll go with Integer.
// You can have this parameterised as <T> at the interface level.
Integer createSomething();
}
enum Enum1 implements CreatorOfSomething {
A, B, C;
#Override
public Integer createSomething() {
return ordinal();
}
}
enum Enum2 implements CreatorOfSomething {
X { // you can override the method for individual constants
#Override
public Integer createSomething() {
// .....
}
},
Y { ....
}
Then your method would look like:
public void doSomething(CreatorOfSomething creator) {
creator.createSomething();
}
The code you posted does not even compile. Nor could we run it. Next time please provide an SSCCE in which you address your question.
Here's the solution for the problem you have:
abstract class NumberOne {
public abstract <T extends Enum<T>> void doSomething(T pEnum);
}
enum Enum1 {
A, B
}
enum Enum2 {
C, D
}
public class NumberTwo extends NumberOne {
#Override public <T extends Enum<T>> void doSomething(final T pEnum) {
System.out.println("Value: " + pEnum);
}
public static void main(final String[] args) {
final NumberTwo n2 = new NumberTwo();
n2.doSomething(Enum1.A);
n2.doSomething(Enum2.D);
}
}
Related
public class ClassX<T> implements Comparable<ClassX<T>> {
private T o;
public ClassX(T o) {
this.o = o;
}
public T getObject() {
return o;
}
public void setObject(T o) {
this.o = o;
}
#Override
public int compareTo(ClassX<T> arg0) {
return o.compareTo(arg0.o);
}
}
If I have a class like this and I want to implement the Comparable interface, I read that I have to change ClassX<T> to ClassX<T extends Comparable<T>>. But what if I also want to use my ClassX for objects that don't implement the Comparable interface, knowing that I would not be able to use the method compareTo() for those objects?
Another option is, instead of implementing Comparable, have a static method that returns a Comparator, and this method can only be called when the constraint on T is met. So then your ClassX can be used with T that do not implement Comparable, but you can only obtain Comparators for ClassXs with T that do implement Comparable.
public class ClassX<T> {
private T o;
// ...
public static <T extends Comparable<? super T>> Comparator<ClassX<T>> getComparator() {
return (x, y) -> x.o.compareTo(y.o);
}
}
How about creating another layer of hierarchy to support this:
public class NonComparableClassX<T> implements Comparable<NonComparableClassX<T>> {
// ....
#Override
public int compareTo(ClassX<T> arg0) {
// throw Exception;
}
}
public class ClassX<T> extends NonComparableClassX<T> {
// ....
#Override
public int compareTo(ClassX<T> arg0) {
// Implement comparables here
}
}
This way you can encapsulate all objects as ClassX, which can also be of the type NonComparableClassX if need be
What is the reason behind overriding a method/methods of an interface in the sub interface?
for example
interface I{ public void method();}
interface I2 extends I{#Override public void method();}
You may need to change the return type of your method to a sub-type of the original return type. eg:
interface I {
public Object method();
}
interface I2 extends I {
#Override
public Integer method();
}
Or you can add default implementation to the method which is introduced in Java 8. eg:
interface I {
public void method();
}
interface I2 extends I {
#Override
default public void method() {
System.out.println("do something");
}
}
Consider the following abstract class
public abstract class AbstractAssembler {
public abstract <T extends AbstractValue> void transform(T value);
}
and the following extension:
public class MyAssembler extends AbstractAssembler {
#Override
public void transform(MyValue value) {
// ...
}
}
With MyValue
public class MyValue extends AbstractValue {
// ...
}
Eclipse tells me:
The method transform(MyValue) of type MyAssembler must override or implement a supertype method
Why does this not work?
Your transform() method must override the generic abstract transform() method in the super class, i.e. you should have something like:
public class MyAssembler extends AbstractAssembler {
#Override
public <T extends AbstractValue> void transform(T value) {
}
}
If you want to invoke it with an actual type (e.g. MyValue) you should do:
MyValue value = new MyValue();
new MyAssembler().transfer(value);
where explicitly specifying the type-parameter (new MyAssembler().<MyValue>transfer(value);) is optional, as it will be inferred by the compiler.
If you however wish MyAssember's transform method to work only with MyValue, then you should do:
public class MyAssembler extends AbstractAssembler<MyValue> {
#Override
public void transform(MyValue value) {
}
}
In the following:
public interface SomeInteface<A, B> {
public B doSomething(A a);
}
I want to implement a version where the method doSomething returns the parameter a back.
I tried a Holder class;
class Holder<A> {
public A value;
public(A a){this.value = a;}
}
and return Holder. However, I am not sure how to define an implementation class of SomeInterface so that I am able to do this.
The following does not even compile:
public class SomeImplementation<X> implements SomeInterface<T> {
private class Holder<A> {
public A value;
public class Holder<A>{
public A value;
public(A a){this.value = a;}
}
}
class Implementation<A, Holder<A>> implements SomeInterface<A, Holder<A>>{
public Holder<A> doSomething(A a){
//do stuff
return new Holder(a);
}
}
}
What am I messing up here?
It needs to be
class Implementation<A> implements SomeInteface<A, Holder<A>>{
public Holder<A> doSomething(A a){
//do stuff
return new Holder<A>(a);
}
}
In the classname you define the generic variables and their constraints. You don't need a Holder variable.
I don't understand why you make it so difficult. You say
I want to implement a version where the method doSomething returns the
parameter a back.
Well, you can do just that:
public class SomeImplementation<A> implements SomeInterface<A, A> {
public A doSomething(A a) {
// do stuff
return a;
}
}
No need for a Holder class.
The interface SomeInterface does not put any constraints on the type parameters, so there's no reason why they can't be the same.
Alternatively, you can allow your implementation to be parameterized with two different types A and B where A extends B (could be useful in some cases):
public class SomeImplementation<A extends B, B> implements SomeInterface<A, B> {
public B doSomething(A a) {
// do stuff
return a;
}
}
Let's say I have ClasseA implements I, how do I do something like:
public class Classe<T> {
void function(Class<T> param) {
...
}
}
Classe<I> c=new Classe();
c.function(ClasseA.class);
Since ClasseA implements the interface I, I would like function to accept either a class literal of type ClasseA or a class implementing I.
Something like this should work:
public Class Classe<T extends I> {
void function(Class<T> param) {
...
}
}
There is a good tutorial about generics available here: http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
A possible solution to your problem:
public class Snippet {
static class Classe<T> {
public void function(Class<? extends T> param) {
System.out.println(param);
}
}
interface I {
}
class ClasseA implements I {
}
public static void main(String[] args) {
Classe<I> c = new Classe();
c.function(ClasseA.class);
}
}
You can specify constraints on the type this way: Classe<T extends I>