tags:

views:

142

answers:

4

Hi,

Here's the relevant code:

public interface Artifact {}    
public interface Bundle implements Artifact {}
public interface Component implements Artifact {}

public interface State<T extends Artifact> {
    void transition(T artifact, State<T> nextState);
}

This allows me to define this enum:

enum BundleState implements State<Bundle> {

    A, B, C;

    public void transition(Bundle bundle, State<Bundle> nextState) {}
    }
}

But the method signature that I want is:

    public void transition(Bundle bundle, BundleState nextState) {}
    }

But this does not compile. Obviously the problem lies with how I've defined T in the State interface, but I can't figure out know how to fix it.

Thanks, Don

+3  A: 

Methods are not contravariant in Java. You could overload and have both, but there wouldn't be much point.

Possibly, you could declare State as something like:

public interface State<THIS extends State<THIS, A>, A extends Artifact> {
    void transition(A artifact, THIS nextState);
}

THIS extends State<THIS, A> is possibly wrong. It depends on what you want to do.

(Single letter enum constants are probably a bad idea, particularly when mixed with generics parameters.)

Tom Hawtin - tackline
+11  A: 

Things might start getting unwieldly, but you could change State to:

public interface State<T extends Artifact, U extends State<T, U>> {
    void transition(T artifact, U nextState);
}

And change BundleState to:

public enum BundleState implements State<Bundle, BundleState> {
    A, B, C;

    public void transition(Bundle bundle, BundleState nextState) {}
}
Kirk Woll
+1  A: 

transition(Bundle, BundleState) doesn't match your current State interface unless you change it as suggested here by others. You could also preserve the interface with

enum BundleState implements Artifact, State<BundleState> {
    A, B, C;
    public void transition(BundleState bundle, State<BundleState> nextState)
    {
    }
}
Steve B.
A: 
enum BundleState implements State<Bundle> 
{
    A, B, C;

    public void transition(Bundle bundle, BundleState nextState) 
    {
        transition(bundel, (State<Bundle>)nextState);
    }

    public void transition(Bundle bundle, State<Bundle> nextState) {}
}
irreputable