Codependent/circular generics loop - java

Problem:
I have two interfaces (here GenCarry and Gen):
public interface GenCarry<T extends Gen> {
GenCarry<T> setGen(T gen);
}
public interface Gen<T extends GenCarry> {
void applyOn(T carry);
}
It works when I ignore the 'rawtypes' Warning, but trying to complete them I don't get too far:
GenCarry<T extends Gen<GenCarry<T>>>
Gen<C extends GenCarry<Gen<C>>> -> error: not a valid substitute for the bounded parameter.
Question:
How would an interface like that look if complete - or is that even possible?
Is there a better approach to "generalize" an interface like that?

You can define two type parameters:
public interface GenCarry<K extends GenCarry<K, T>, T extends Gen<T, K>> {
GenCarry<K, T> setGen(T gen);
}
public interface Gen<K extends Gen<K, T>, T extends GenCarry<T, K>> {
void applyOn(T carry);
}
class StringGenCarry implements GenCarry<StringGenCarry, StringGen> {
#Override
public StringGenCarry setGen(StringGen client) {
...
}
}
class StringGen implements Gen<StringGen, StringGenCarry> {
#Override
public void applyOn(StringGenCarry network) {
...
}
}

Related

Java bounded type parameters in interface implementation

I want to combine the use of bounded type parameters with DI spring. That is, I would like to declare an interface:
public abstract class BaseClass {
}
public class ChildClass extends BaseClass {
}
public interface SomeInterface {
<T extends BaseClass> void update(T impl);
}
and make its implementation:
#Service
public class Impl1 extends SomeInterface {
#Override
void update(ChildClass impl) {
}
}
That is, I want to declare in the interface a general type condition for implementations and use a specific type of successor in the implementation.
Is it possible?
You can:
public interface SomeInterface<T extends BaseClass> {
void update(T impl);
}
and then:
#Service
public class Impl1 extends SomeInterface<ChildClass> {
#Override
void update(ChildClass impl) {
}
}

How can I override this method in this interface (see code)?

I have an interface called A:
public interface A {
void X(T t);
}
I then have two subclasses (B and C) that implement this interface, but each of them pass a different type to X lets say B passes type foo and C passes type bar:
public class B implements A {
#Override
public <T extends foo> void X(T type1)
}
public class C implements A {
#Override
public <T extends bar> void X(T type2)
}
What am I doing wrong and why doesn't this work? The compiler keeps telling me that "Method does not override method from its superclass".
Thanks in advance!
Even with generic methods, when they are overridden, the generics must match exactly.
One way that might not meet your requirements is to remove the upper bounds on the implementing class, e.g.
class B implements A {
#Override
<T> void X(T type1) { /* impl */ }
}
But if you need the upper bound, then represent the upper bound with a type parameter on the interface.
interface A<U> {
<T extends U> void X(T t);
}
Then you can supply the type argument for the upper bound in the implementing classes.
class B implements A<Foo> {
#Override
public <T extends Foo> void X(T type1) { /* impl */ }
}
class C implements A<Bar> {
#Override
public <T extends Bar> void X(T type2) { /* impl */ }
}
But because anything you can call on T you can also call on Foo or Bar, maybe the methods don't need to be generic.
interface A<T> {
void X(T t);
}
class B implements A<Foo> {
#Override
public void X(Foo type1) { /* impl */ }
}
class C implements A<Bar> {
#Override
public void X(Bar type2) { /* impl */ }
}

Missing type arguments for generic class

Using a library with an abstract class A and interfaces I and J, I get the following warning message when I extend / implement the class / interfaces:
Missing type arguments for generic class J<T>.
As a MWE, the classes are as follows (T and S are generic type parameters):
public abstract class A {}
public interface I<T extends A> {
public <S extends T> void doStuff(J<? super S> param);
}
public interface J<T extends A> {
public void doOtherStuff();
}
Here are my classes:
public class AExtended extends A {}
public class IImplemented implements I<AExtended> {
#Override
public void doStuff(J param) {}
}
Explicitly using the class AExtended as below does not properly implement doStuff() from I:
public class IImplemented implements I<AExtended> {
#Override
public void doStuff(J<AExtended> param) {}
}
You're not overriding doStuff in IImplemented because the method is not generic and the type bounds are not present. This version of doStuff should work for you:
public <S extends AExtended> void doStuff(J<? super S> param) {}
Notice that since the type of I is AExtended it is used appropriately here, and the lower bound in the wildcard type for J is also included.
try with:
public class IImplemented implements I<AExtended> {
#Override
public <S extends AExtended> void doStuff(J<? super S> param) {
// ...
}
}

How to define an interface method to accept a class or any of its subclasses in Java?

Suppose I have a class called Animal and an interface called AnimalTrainer.
public interface AnimalTrainer
{
void trainAnimal(Animal animal);
}
Now, the problem arises when I want to write an implementation that trains only Lion, for example, where Lion extends Animal.
public class LionTrainer implements AnimalTrainer
{
public void trainAnimal(Lion lion)
{
// code
}
}
But this doesn't work. How can I define the trainAnimal method in AnimalTrainer such that the above LionTrainer implementation is possible? Or would I have to change the LionTrainer implementation?
You need to type AnimalTrainer
public interface AnimalTrainer<T extends Animal>
{
public void trainAnimal(T animal);
}
public class LionTrainer implements AnimalTrainer<Lion>
{
public void trainAnimal(Lion lion);
}
Use generics:
public interface AnimalTrainer<T extends Animal> {
void trainAnimal(T animal);
}
class LionTrainer implements AnimalTrainer<Lion> {
public void trainAnimal(Lion lion) {...}
}
You should use generic types...
public interface AnimalTrainer<T extends Animal>
{
public void trainAnimal(T animal);
}
then LionTrainer implements AnimalTrainer<Lion> ...

Java generics method overriding

I have interface:
public interface CartService extends RemoteService{
<T extends ActionResponse> T execute(Action<T> action);
}
I wish override 'execute' method in implementation:
public class XX implements CartService {
#Override
public <GetCartResponse> GetCartResponse execute(GetCart action) {
// TODO Auto-generated method stub
return null;
}
}
But receive compiler error:
The method execute(GetCart) of type XX must override or implement a supertype method
GetCart & GetCartResponse:
public class GetCart implements Action<GetCartResponse>{
}
public class GetCartResponse implements ActionResponse {
private final ArrayList<CartItemRow> items;
public GetCartResponse(ArrayList<CartItemRow> items) {
this.items = items;
}
public ArrayList<CartItemRow> getItems() {
return items;
}
}
How can I override this method ?
The problem is the definition of the interface vs what the erausre should look like for your impl. In your example you have:
<T extends ActionResponse> T execute(Action<T> action);
public <GetCartResponse> GetCartResponse execute(GetCart action);
but according to the interface definition the implementation method should read:
public GetCartResponse execute(Action<GetCartResponse> action);
So I think you either need to change the signature of your interface or add another type parameter such as:
public interface CartService extends RemoteService{
<T extends ActionResponse, U extends Action> T execute(U action);
}
or possibly something along the lines of:
public interface CartService extends RemoteService{
<T extends ActionItem> ActionResponse<T> execute(Action<T> action);
}
Your interface specifies that implementing classes must define that method for all T extends ActionResponse. You want to define them for specific actions, and responses - I think your interface needs to be
public interface CartService<T extends ActionResponse, A extends Action<T>>
extends RemoteService {
public T execute(A action)
}
and then implementation would be
public class XX implements CartService<GetCartResponse,GetCart> {
//...
}
As written, you may not need to explicitly parametrize with an extension of Action type - as long as you can deal with any kind of Action that is parametrized by GetCartResponse and don't rely on specifics of the GetCart action. In which case, your interface should look something like:
public interface CartService<T extends ActionResponse> extends RemoteService {
public T execute(Action<T> action);
}
and implementation
public class XX implements CartService<GetCartResponse> {
public GetCartResponse execute(Action<GetCartResponse> action) {
//...
}
}
Use
public <GetCartResponse extends ActionResponse>
GetCartResponse execute(GetCart action) {
//do stuff
}
as the signature for the execute method in CartService, it should work.
I ahve tested that the follwing compiles; just substituted ActionResponse with Integer, and Action with List, for convenience.
CartService:
public interface CartService {
<T extends Integer> T execute(List<T> action);
}
XX:
public class XX implements CartService {
public <T extends Integer> T execute(List<T> action) {
throw new UnsupportedOperationException("Not supported yet.");
}
}

Categories

Resources