In libgdx you can create a pool easily by using the abstract class Pool.
Since it is an abstract class you need to override it's methods anonymously when constructing it like this:
public Pool<String> pool = new Pool<String>() {
#Override
protected String newObject() {
return new String();
}};
What I'm trying to do now is put a wildcard for the generic type T which extends a abstract BaseClass like this:
protected static Pool<? extends GameCommand> commandPool = new Pool<? extends GameCommand>() {
#Override
protected <T extends GameCommand> newObject() {
return new T();
}
};
But it won't work. How can I get it?
What kind of type will I have to insert when overriding newObject()?
EDIT:
Pool references it's abstract method like this:
abstract public class Pool<T> {
(...)
abstract protected T newObject ();
(...)
}
If you make a small change like making a factory method, it can be done fairly simply. As long as you can assure that all subclasses of GameCommand have a default constructor. (Although, you could get around that with Objenesis).
Just do the following:
public static <T extends GameCommand> Pool<T> createCommandPool(final Class<T> clazz) {
return new Pool<T>() {
#Override protected T newObject() {
try {
return clazz.newInstance();
} catch (Exception e) {
throw new RuntimeException(e); // cause there isn't really much else you can do.
}
}
};
}
public static void main(String[] args) {
Pool<? extends GameCommand> gcPool = createCommandPool(GameCommand.class);
// MyCommand extends GameCommand
Pool<? extends GameCommand> mcPool = createCommandPool(MyCommand.class);
}
Related
This question already has answers here:
how to inherit Constructor from super class to sub class
(6 answers)
Closed 7 years ago.
I have created an abstract base class BaseModelDao with three constructors. When I create a class SubscriberScoreDao that extends BaseModelDao I have to redefine all three constructors in the subclass in order to avoid compile time errors. Is there a way to take advantage of the constructors I have defined in my BaseModelDao without having to reimplement the same logic in every subclass?
BaseModelDao
public abstract class BaseModelDao<T extends Model> {
private static final String TAG = BaseModelDao.class.getSimpleName();
private List<T> mModelList;
protected BaseModelDao() {
mModelList = new ArrayList<>();
}
protected BaseModelDao(Response<T>[] responseArray) {
mModelList = fromResponseArray(responseArray);
}
protected BaseModelDao(Response<T> response) {
mModelList = fromResponse(response);
}
public List<T> getModelList() {
return mModelList;
}
public abstract Class<T> getModelClass();
private List<T> fromResponse(Response<T> response) {
List<T> responseList = response.getResultData();
return responseList;
}
public List<T> fromResponseArray(Response<T>[] responseArray) {
return fromResponse(getResponseObjectFromArray(responseArray));
}
// more helper methods...
}
SubscriberScoreDao
public class SubscriberScoreDao extends BaseModelDao<SubscriberScore> {
public static final String TAG = SubscriberScoreDao.class.getSimpleName();
public SubscriberScoreDao(){
super();
}
public SubscriberScoreDao(Response<SubscriberScore>[] responseArray) {
super(responseArray);
}
public SubscriberScoreDao(Response<SubscriberScore> responseArray) {
super(responseArray);
}
#Override
public Class<SubscriberScore> getModelClass() {
return SubscriberScore.class;
}
}
The constructors shown above are the ones I am trying to eliminate. When I want to use the SubscriberScoreDao in code it looks like this.
LendingRestClient.getInstance().getSubscriberScoring(new Callback<Response<SubscriberScore>[]>() {
#Override
public void success(Response<SubscriberScore>[] responseArray, retrofit.client.Response response) {
mSubscriberScoreDao = new SubscriberScoreDao(responseArray);
}
#Override
public void failure(RetrofitError error) {
}
});
If the three constructors that call super() are not defined in the SubscriberScoreDao then the code throws a compile time error at this line:
mSubscriberScoreDao = new SubscriberScoreDao(responseArray);
Error:
Is there a way to not define the constructors in every subclass and avoid this error?
You could declare the constructor (in the base class) with a vararg:
class Super<T> {
private List<T> responses;
public Super(Response<T>...responses) {
this.responses = Arrays.asList(responses);
}
}
Your subclass would only have to declare 1 constructor, which takes care of the functionality of all 3 of the constructors you have.
class Sub extends Super<SubscriberScore> {
public Sub(Response<SubscriberScore>...responses) {
super(responses);
}
}
You can now instantiate Sub as:
new Sub();
new Sub(new Response<SubscriberScore>());
new Sub(new Response<SubscriberScore>[] {
});
I have generic class :
public class Test<T> {
private Test<? extends T> myInstance;
public Test<? extends T> getInstance () {
return myInstance;
}
public void setInstance (Test<? extends T> argType) {
this.myInstance = argType;
}
}
And I have two classes in my class hierarchy relations:
public abstract class Alphabet {
//code here
}
and
public class A extends Alphabet{
public A() {
super();
System.out.print("This is A call");
}
}
Finally I have a class where I want to store make generic class Test with particular type and set new Instance of Object -> A through setInstance() method:
public static void main(String[] args) {
List<Alphabet> list = new ArrayList<Alphabet>();
Test<Alphabet> tAlphabet = new Test<Alphabet>();
tAlphabet.setInstance(new A()); //Here is compilation ERROR
}
But I have got the compilation error in line tAlphabet.setInstance(new A());
What is the issue with my generic class?
Your instance is a Test object as it's currently written, and you are supplying it with an Alphabet object instead. You probably want your instance to be of type Alphabet:
public class Test<T> {
private T myInstance;
public T getInstance() {
return myInstance;
}
public void setInstance(T argType) {
myInstance = argType;
}
}
This way, your Test stores an Alphabet instead of another Test.
It seems you have made things more complicated than needed. You probably want this in your Test class instead of what you actually have:
private T myInstance;
public T getInstance () {
return myInstance;
}
public void setInstance (T argType) {
this.myInstance = argType;
}
With this arrangement you would be free to setInstance(new A()) on a Test<Alphabet> instance.
It is possible to narrow return type in overriding methods in Java.
But is it possible to force this narrowing during declaration?
For example, this may be good in the pattern, where inner class is subclassed simultaneously with outer one:
public class Try_ForceNarrow {
public interface IMember {
}
public interface Container<M extends IMember> {
M createMember();
}
public static class A implements Container<A.Member> {
#Override
public Member createMember() {
return new Member();
}
public class Member implements IMember {
}
}
public static class B extends A implements Container<B.Member> {
#Override
public Member createMember() {
return new Member();
}
public class Member extends A.Member {
}
}
public static void main(String[] args) {
}
}
This code fails compile with an error of "The interface Container cannot be implemented more than once with different arguments".
How to avoid this?
Of course, I can just write
public static class B extends A {
#Override
public Member createMember() {
return new Member();
}
public class Member extends A.Member {
}
}
But this way I can forget to override createMember() and violate the pattern.
And what about A<T> implements Container<T> ? You can restrict T further as you wanted...
It appears to me that you want each subclass C to have a createMember factory method that returns a new object that has the same type. The problem is that if C1 provides a factory method that returns C1, and then C2 extends C1, there's no way to force C2 to provide its own method--it could just inherit the one from C1.
I don't think there's a solution that will catch errors at compile time, but maybe you can do something that catches the error at run time:
abstract class MemberBase {
protected abstract MemberBase doCreateMember();
protected abstract Class<?> memberClass();
public MemberBase createMember() {
MemberBase result = doCreateMember();
if (result.getClass() != memberClass()) {
throw new RuntimeException("createMember returned the wrong class");
}
return result;
}
}
public static class A extends MemberBase {
#Override
protected Member doCreateMember() {
return new Member();
}
#Override
protected Class<?> memberClass() {
return Member.class;
}
public class Member implements IMember {
}
}
public static class B extends A {
// If you forget to define this, the doCreateMember in A will be
// inherited, but it will return the wrong class and lead to a
// run-time exception
#Override
protected Member doCreateMember() {
return new Member();
}
#Override
protected Class<?> memberClass() {
return Member.class;
}
public class Member extends A.Member {
}
}
I haven't tested this, and I'm not sure it accomplishes what you are looking for. Plus I may have gotten some syntax wrong. But maybe this, or a modification of it, might be useful.
I believe this fulfills what you are trying to do.
You can create a new abstract class that implements Container which allows you to continually extend or narrow the generics, but you need to declare each class static:
class Try_ForceNarrow {
public interface IMember {
}
public interface Container<M extends IMember> {
M createMember();
}
//The abstract class that lets you continually extend or "narrow"
public static abstract class A<E extends A.Member> implements Container<E> {
public static class Member implements IMember {
}
}
//Here is the first class that extends the Abstract Class A
public static class B extends A<B.Member> { //This class now Implements Container<B.Member>
#Override
public Member createMember() {
return new Member();
}
//Since this is the first extension we will extend A.Member
public static class Member extends A.Member {
}
}
//This is an additional class that extends A but we want to extend the functionality of B.Member also.
public static class C extends A<C.Member> { //This class now Implements Container<C.Member>
#Override
public Member createMember() {
return new Member();
}
//C.Member properly extends B.Member
//if this class is going to be extended this needs to be static
public class Member extends B.Member {
}
}
}
And of course per your requirements if you remove
#Override
public Member createMember() {
return new Member();
}
From the extending sub-classes you get a compile error.
Of course it will fail, your class A implements Container<A.Member>, but your class B extends A but also implements Container<B.Member> which is like class B extends A implements Container<A.Member> Container<B.Memeber> , and in terms of the compiler, there is no difference between Container<A.Member> and Container<B.Member> due to type erasure, after compilation, all generics information will be lost, so there is no <……> after type erasure, only their upper bounds and lower bounds exist, your type parameters are unbounded so they will erase to the same type, after erasure, your class B literally looks like this class B extends A implements Container Container which is fundamentally wrong. You can narrow the return type on overrides which is called covariant return type, this will also create a bridge method in the VM to preserve porlymorphism in Generics.
I have some code as follows (excerpt):
public interface Event<S> {
S getSource();
}
public interface Subscriber<E> {
void update(E event);
}
public interface EventPublisher<S, E extends Event<S>> {
void addSubscription(S source, Subscriber<E> subscriber);
void removeSubscription(S source, Subscriber<E> subscriber);
}
public class SubscriptionManager<S, E extends Event<S>> implements Subscriber<E>, EventPublisher<S, E> {
...
}
public class MyEvent implements Event<MyEventSource> {
...
}
This all works fine, however, my problem is when I try something like this:
public class MyEventHandler {
private final SubscriptionManager<Class<? extends Event<?>>, ? extends Event<?>> subscriptionManager = new SubscriptionManager<>();
Subscriber<? extends Event<?>> subscriber = ...;
subscriptionManager.addSubscription(MyEvent.class, subscriber); **// Compile error**
}
I get the following error:
The method addSubscription(Class<? extends Event<?>>, Subscriber<capture#3-of ? extends Event<?>>) in the type SubscriptionManager<Class<? extends Event<?>>,capture#3-of ? extends Event<?>> is not applicable for the arguments (Class<MyEvent>, Subscriber<capture#5-of ? extends Event<?>>)
Can anyone tell me what's wrong?
Thanks
To be honest with you I think there's some design error in your code. It almost looks like a perfectly designed pattern, but something doesn't add up. You can probably omit half of generic parameters and make it more straightforward.
Please consider the code below. Entire framework is parametrized by a single parameter. Everything compiles and there are no raw types used.
Also, note that MyEvent is never used in the framework definition. It's a convenience class.
You can safely invoke subscriptionManager.update(new MyEvent()); somewhere in your code.
More complicated arrangements are possible too, but I believe that's the one you need.
Please let me know if that works for you.
static interface Event<S> {
S getSource();
}
static interface Subscriber<S> {
void update(Event<S> event);
}
static interface EventPublisher<S> {
void addSubscription(Class<S> sourceClass, Subscriber<S> subscriber);
void removeSubscription(Class<S> sourceClass, Subscriber<S> subscriber);
}
static class SubscriptionManager<S> implements Subscriber<S>, EventPublisher<S> {
public void addSubscription(Class<S> sourceClass, Subscriber<S> subscriber) {
}
public void removeSubscription(Class<S> sourceClass, Subscriber<S> subscriber) {
}
public void update(Event<S> event) {
}
}
static class MyEvent implements Event<String> {
public String getSource() {
return null;
}
}
static class MyEventHandler {
private final SubscriptionManager<String> subscriptionManager = new SubscriptionManager<String>();
public MyEventHandler() {
Subscriber<String> subscriber = null;
subscriptionManager.addSubscription(String.class, subscriber);
}
}
I have a class A that works with List<String>. But nobody outside this class should need to know that it works with strings. However, I also want to supply the concrete implementation the class should use for it's List (via dependency injection).
A should look like this
public class A {
private ListFactory listFactory; //this gets injected from the outside
public A(ListFactory listFactory) {
this.listFactory = listFactory;
}
public void a() {
List<String> = listFactory.createList();
//...
}
}
And the caller class B something like this
public class B {
public void b() {
ListFactory factory = new ArrayListFactory(); //we want class A to use ArrayList
A a = new A(factory);
//...
}
}
ListFactory would be an interface which is implemented by ArrayListFactory to create ArrayLists.
Quintessence:
I don't want that B has to mention String somewhere. And I also don't want that A has to mention ArrayList somewhere.
Is this possible? And how would ListFactory and ArrayListFactory have to look?
This is simpler than you're making it, I think:
public interface Factory {
public <T> List<T> create();
}
public class FactoryImpl implements Factory {
public <T> ArrayList<T> create() {
return new ArrayList<T>();
}
}
...
Factory f = new FactoryImpl();
List<String> strings = f.create();
...
Seems you wrote all you need. Factories will look like:
interface ListFactory<K, T extends List<K>> {
T create();
}
class ArrayListFactoryImpl implements ListFactory<String, ArrayList<String>> {
public ArrayList<String> create() {
return new ArrayList<String>();
}
}
class Sample {
public static void main(String[] args) {
ListFactory<String, ArrayList<String>> factory = new ArrayListFactoryImpl();
factory.create().add("string");
}
}
Another attempt thanks to more clear understanding of the issue:
interface ListFactory<T extends List> {
T create();
}
class ArrayListFactoryImpl implements ListFactory<ArrayList> {
public ArrayList create() {
return new ArrayList();
}
}
class ListWrapper<T> implements List<T> {
private final List impl;
public ListWrapper(List impl) {
this.impl = impl;
}
public boolean add(T t) {
if (!String.class.isAssignableFrom(t.getClass()))
throw new RuntimeException("Aaaaa");
return impl.add(t);
}
// so on...
}
class A {
A(ListFactory factory) {
List<String> stringsOnly = new ListWrapper<String>(factory.create());
}
}
class Sample {
public static void main(String[] args) {
ListFactory<ArrayList> factory = new ArrayListFactoryImpl();
new A(factory);
}
}