I have a question.
How I can define an Enum type for multiple static classes with a different object as Enum?
Example:
public abstract class AbstractClass
{
public Enum<?> AbstractMethod();
}
public class StaticClass extends AbstractClass
{
public enum en
{
FOO3,
FOO4
}
#Override
public Enum<en>[] AbstractMethod()
{
return en.values();
}
}
public class StaticClass2 extends AbstractClass
{
public enum en
{
FOO1,
FOO2
}
#Override
public Enum<en>[] AbstractMethod()
{
return en.values();
}
}
But that code throws an error:
The method public boolean AbstractMethod(Enum<ObjectX> en1) dosn't exsist in AbstractClass (X is the Number of the Object)
Doing this it works but throws RawTypes warning:
public abstract class AbstractClass
{
public Enum[] AbstractMethod();
}
public class StaticClass extends AbstractClass
{
public enum en
{
FOO3,
FOO4
}
#Override
public Enum[] AbstractMethod()
{
return en.values();
}
}
public class StaticClass2 extends AbstractClass
{
public enum en
{
FOO1,
FOO2
}
#Override
public Enum[] AbstractMethod()
{
return en.values();
}
}
Is this what you mean?
Enum:
public enum Fruits {
APPLE, ORANGE;
}
Classes:
public static abstract class Parent {
public abstract <E extends Enum<?>> void printEnum(final E e);
}
public static class Child extends Parent {
#Override
public <E extends Enum<?>> void printEnum(final E e) {
System.out.println(e.name());
}
}
Usage:
new Child().printEnum(Fruits.ORANGE); // Prints ORANGE
Related
I have two classes which have to getMethodes which returns an ArrayList of two Objects which implements a interface
public class MyClass1 implements IMyClasses<MyObject1>{
public ArrayList<MyObject1> getMyObject() { ... }
}
public class MyClass2 implements IMyClasses<MyObject1>{
public ArrayList<MyObject1> getMyObject() { ... }
}
MyObject1 and MyObject2 implements IMyObject
In my ManagerClass I would like to implement a function which can return any IMyObject implementation
ArrayList<IMyObject) get() {
if (...) {
return new MyClass1().getMyObject();
} else {
return new MyClass2().getMyObject();
}
}
Before I have introduced the Generic typ on MyClass1 and MyClass2 it worked fine, but with the Generic which I need to get the proper object if needed, I'm not able to return the object which has as return type the Interface?
Some help?
Edit this is a full working example, the trick is to do <? extend IMyObject> thx to #Alexander.Furer
public class ManagerClassTest {
public interface IManagerClass {
public ArrayList<? extends IMyObject> getMyObject(boolean myObject1);
}
public interface IMyClass<I>{
public ArrayList<I> getMyObject();
}
public interface IMyObject {}
public class MyObject1 implements IMyObject {}
public class MyClass1 implements IMyClass<MyObject1> {
#Override
public ArrayList<MyObject1> getMyObject() {
return new ArrayList<MyObject1>();
}
}
public class MyObject2 implements IMyObject {}
public class MyClass2 implements IMyClass<MyObject2> {
#Override
public ArrayList<MyObject2> getMyObject() {
return new ArrayList<MyObject2>();
}
}
public class ManagerClass implements IManagerClass {
private ArrayList<MyObject1> getMyObject1() {
return new MyClass1().getMyObject();
}
private ArrayList<MyObject2> getMyObject2() {
return new MyClass2().getMyObject();
}
#Override
public ArrayList<? extends IMyObject> getMyObject(boolean myObject1) {
if (myObject1) {
return new MyClass1().getMyObject();
} else {
return new MyClass2().getMyObject();
}
}
}
}
ArrayList<MyObject1> is not of type ArrayList<IMyObject> ,BTW, you have a typo :ArrayList<IMyObject)
Declare the get method of ManagerClass as :
ArrayList<? extends IMyObject> get() {
}
I am trying to implement base abstract class in android.
My base abstract class is BaseItemPresenter class. Class is below :
public abstract class BaseItemPresenter<T extends MvpView> extends BasePresenter<T> {
public abstract void loadFromDevice();
public abstract void loadFromFile();
public abstract void backup(List<? extends BaseBackupItem> list);
public abstract void delete(List<? extends BaseBackupItem> list);
public abstract void restore(List<? extends BaseBackupItem> list);
public abstract void sort(int sortType, boolean isAscending);
public abstract void sort(List<? extends BaseBackupItem> list, int sortType, boolean isAscending);
public abstract void filter(List<? extends BaseBackupItem> list, Class<? extends MvpView> filterOptions);
}
and I am implementing this class with ItemPresenter1 class. Code is below :
public class ItemPresenter1 extends BaseItemPresenter<MvpView> {
#Override
public void loadFromDevice() {
}
#Override
public void loadFromFile() {
}
#Override
public void backup(List<Item1> list) {
}
#Override
public void delete(List<Item1> list) {
}
#Override
public void restore(List<Item1> list) {
}
#Override
public void sort(int sortType, boolean isAscending) {
}
#Override
public void sort(List<Item1> list, int sortType, boolean isAscending) {
}
#Override
public void filter(List<Item1> list, Class<View1> filterOptions) {
}
}
Item1 class is extending BaseBackupItem class.
View1 class is extending MvpView class.
public class Item1 extends BaseBackupItem {
}
public class View1 extends MvpView {
}
so, how should I achieve this problem :
from :
public abstract void backup(List<? extends BaseBackupItem>);
to :
#Override
public void backup(List<Item1>);
error :
Method does not override method from its superclass.
You need to add a new type parameter to the class definition of BaseItemPresenter in order to specify the expected type of your List as next:
public abstract class BaseItemPresenter<T extends MvpView, I extends BaseBackupItem>
extends BasePresenter<T> {
...
public abstract void backup(List<I> list);
public abstract void delete(List<I> list);
public abstract void restore(List<I> list);
...
}
Then your class ItemPresenter1 will be declared as next:
public class ItemPresenter1 extends BaseItemPresenter<MvpView, Item1 > {
...
#Override
public void backup(List<Item1> list) {
I have three classes:
class ClassR {}
class ClassA<T extends ClassR>{}
class ClassB<E extends ClassA<T extends ClassR>> extends ClassA<T> {
void foo(T param) {
}
void bar(E param) {
}
}
The third class does not compile unless I change it to
class ClassB<E extends ClassA<T>, T extends ClassR> extends ClassA<T> {
void foo(T bar) {
}
void bar(E param) {
}
}
Is there a way to keep only E parameter I need to pass when creating ClassB, and T being inferred? For example, it would be convenient to use:
new ClassB<ClassA<ClassR>>()
instead of:
new ClassB<ClassA<ClassR>, ClassR>()
This even simpler approach might work for you:
class ClassR {}
class ClassA<T extends ClassR>{}
class ClassB<T extends ClassR> extends ClassA<T> {
void foo(T bar) {
}
void bar(ClassA<T> param) {
}
}
And usage then bypasses any reference to ClassA to become:
class SubR extends ClassR {}
ClassB<SubR> obj = new ClassB<SubR>();
Not sure if this is the answer you want but surely the simplest version reads:
class ClassR {
}
class ClassA<T extends ClassR> {
}
class ClassB<T extends ClassR> extends ClassA<T> {
void foo(T bar) {
}
}
public void test() {
ClassB<ClassR> classB = new ClassB<>();
}
As type E extends ClassA you can safely omit the ClassA type parameter in its declaration.Proper ClassA type parameter is enforced in the second parameter to ClassB. See below code for illustration :
class ClassB<E extends ClassA, T extends ClassR> extends ClassA<T> {
private ClassA ob;
public ClassB(E e, T t) {
super(t);
ob = e;
}
}
Usage sample:
class ClassR {
public ClassR() {};
}
class ClassS extends ClassR {
private int x;
public ClassS(int x) {
super();
this.x = x;
}
}
public static void test() {
ClassS data1 = new ClassS(1);
ClassB <ClassB, ClassS> first = new ClassB<>(null, data1);
ClassS data2 = new ClassS(2);
ClassB <ClassB, ClassS> second = new ClassB<>(first, data2);
}
i would like to get rid of these warnings about unchecked conversion and parameterization without surpressing them.
interface Switch {
void toggle();
}
enum A implements Switch {
a1,a2;
#Override public void toggle() {
state=!state;
}
boolean state;
}
enum B implements Switch {
b1,b2;
#Override public void toggle() {
state=!state;
}
boolean state;
}
public class Warnings {
public static void main(String[] args) {
Class<? extends Enum>[] enums=new Class[]{A.class,B.class};
for(Class<? extends Enum> clazz:enums)
try {
Enum s=Enum.valueOf(clazz,args[0]);
((Switch)s).toggle();
} catch(IllegalArgumentException eee) {}
}
}
You can't without writing your own valueOf. Enum is defined as:
class Enum<E extends Enum<E>>
and Enum.valueOf is defined as:
public static <T extends Enum<T>> T valueOf(Class<T> enumType,
String name)
Note the recursive type parameterization which implies that you can only call valueOf with a specific enum class (e.g. A.class), but not with a generic one, as a Class<? extends Enum<?>> is not a match because the two question marks aren't assumed to represent the same (unknown) type by the compiler.
So apart from using generic collections instead of arrays, you have to write your own valueOf method that accepts any enum class.
public class Warnings {
public static void main(final String[] args) {
List<Class<? extends Enum<?>>> enums = new ArrayList<Class<? extends Enum<?>>>();
enums.add(A.class);
enums.add(B.class);
for (Class<? extends Enum<?>> clazz : enums) {
try {
Switch s = valueOf(clazz, args[0]);
s.toggle();
} catch (IllegalArgumentException eee) {
}
}
}
private static Switch valueOf(final Class<? extends Enum<?>> enumClass, final String name) {
Enum<?>[] enumConstants = enumClass.getEnumConstants();
for (Enum<?> constant : enumConstants) {
if (constant.name().equals(name)) {
return (Switch) constant;
}
}
throw new IllegalArgumentException(name + " is not a constant of enum class " + enumClass.getName());
}
}
Don't mix arrays and generics. They do not work well together because generics in java is implemented using type erasure.
This should work.
interface Switch {
void toggle();
}
enum A implements Switch {
a1, a2;
#Override
public void toggle() {
state = !state;
}
boolean state;
}
enum B implements Switch {
b1, b2;
#Override
public void toggle() {
state = !state;
}
boolean state;
}
public class Test {
public static void main(String[] args) {
List<Class<? extends Switch>> enums = new ArrayList<Class<? extends Switch>>();
enums.add(A.class);
enums.add(B.class);
for (Class<? extends Switch> clazz : enums)
try {
Switch s = clazz.getEnumConstants()[0];
((Switch) s).toggle();
} catch (IllegalArgumentException eee) {
}
}
}
How to define a generic return type for an interface, so that it's implementing class can have a return type of its own?
public interface A {
public <T> T doSomething();
}
public class ImplA implements A {
public SomethingElseA doSomething() {
return obj.doSomething();
}
}
public class ImplB implements A {
public SomethingElseB doSomething() {
return obj.doSomething();
}
}
Try something as follows.
interface A<T> {
T doSomething();
}
class ImplA implements A<SomethingElseA> {
public SomethingElseA doSomething() {
...
}
}
class ImplB implements A<SomethingElseB> {
public SomethingElseB doSomething() {
...
}
}
I'm guessing you mean like this? I changed do() to foo() as do is a reserved word...
public interface A<T> {
public T foo();
}
public class ImplA implements A<SomethingElseA> {
#Override
public SomethingElseA foo() {
return obj.doSomething();
}
}
public class ImplB implements A<SomethingElseB> {
#Override
public SomethingElseB foo() {
return obj.doSomething();
}
}