Composition and generics

I'm trying to solve this "composition + generics" situation, and make PostCompany.send(msg) be compatible with the type passed/injected to the class.

What could I change to allow both Fedex and FedexPlus being used as generic Types at PostCompany class, since Fexed's send method expects String as parameter and FeexPlus expects Integer?

interface Poster<T> {
    void send(T msg);
}

class Fedex implements Poster<String> {

    @Override
    public void send(String msg) {
        // do something
    }
}

class FedexPlus implements Poster<Integer> {

    @Override
    public void send(Integer msg) {
        // do something
    }
}

class PostCompany<P extends Poster> {

    private final P poster;

    public PostCompany(P poster) {
        this.poster = poster;
    }

    public void send(??? msg) { // <-- Here 
        this.poster.send(msg);
    }
}

Upvotes: 4

Views: 908

Answers (2)

rgettman
rgettman

Reputation: 178343

You are using the raw form of Poster when defining PostCompany. You need to define another type parameter to capture the type argument for Poster.

Then you can use that new type parameter as the type argument to Poster and as the parameter type to the send method.

class PostCompany<T, P extends Poster<T>> {

and

public void send(T msg) { 

Upvotes: 2

Marcos Vasconcelos
Marcos Vasconcelos

Reputation: 18276

You missed the type of a Poster

class PostCompany<T, P extends Poster<T>> {
    public void send(T msg) { // <-- Here 
        this.poster.send(msg);
    }
}

But it actually better to just type the type of the object

class PostCompany<T> {

    private final Poster<T> poster;

    public PostCompany(Poster<T> poster) {
        this.poster = poster;
    }

    public void send(T msg) { // <-- Here 
        this.poster.send(msg);
    }
}

Since you will always be using the interface methods of Poster

Upvotes: 7

Related Questions