tags:

views:

68

answers:

2

Examine the code below

public abstract class ClassA<ClassBType extends ClassB<ClassCType>,ClassCType extends ClassC> {
    public void method(ClassBType type) {
        type.myClassA = this;  //Error.  Type mismatch: cannot convert from TestGameMain.ClassA<ClassBType,ClassCType> to TestGameMain.ClassA<TestGameMain.ClassB<ClassCType>,ClassCType>
    }
}

public abstract class ClassB<ClassCType extends ClassC> {
    ClassA<ClassB<ClassCType>,ClassCType> myClassA;

    private void testMethod() {
        myClassA.method(this);
    }
}

public abstract class ClassC {}
}

What's the correct way to fix this problem?

Edit: I've updated the code above, which does not compile.

+5  A: 

Unless I'm really missing something in your question, this does the job:

ClassA<ClassB<ClassCType>, ClassCType> myClassA;

I would have to know more about how you instantiate these animals to know if getting an instance of ClassA to have those parameters is a problem that requires solving.

Yishai
That fixes the original problem asked by the question. But my problem was actually more specific, and involved the code above. I've added your code, and I've also added something to the effect that causes the issue I'm really seeing
Ed Marty
+1  A: 

Your example is overly complicated - you can demonstrate the same issue even without ClassC:

public abstract class ClassA<ClassBType extends ClassB> {
    public void method(ClassBType type) {
        type.myClassA = this; 
    }
}

public abstract class ClassB {
    ClassA<ClassB> myClassA;

    private void testMethod() {
        myClassA.method(this);
    }
}

The problem comes down to variance: there is no inheritance relationship between a ClassA<ClassB> and a ClassA<ClassBType> (nor should there be), so the assignment can't be made. Given the cryptic nature of this example, I'm not sure if this is actually a "solution" to your problem, but the following code does compile:

public abstract class ClassA<ClassBType extends ClassB> {
    public void method(ClassB type) {
        type.myClassA = this; 
    }
}

public abstract class ClassB {
    ClassA<? extends ClassB> myClassA;

    private void testMethod() {
        myClassA.method(this);
    }
}
kvb
The problem with the simplification is that it hides an issue. If ClassB is itself parameterized, referencing that using extends can get problematic. `ClassA<? extends ClassB<? extends ClassC>>` is the syntax, but it isn't usable in all cases. Then you get into `<T extends ClassA<? extends ClassB<? extends ClassC>>>`
Yishai
@Yishai - Yes, you're right that the original case was even more complicated, and that a true solution will therefore also be more complicated than what I suggested. However, I hoped that by looking at the solution to the simplified problem the OP would be able to extend it to the full problem. The crux of the issue didn't depend on `ClassC`'s existence.
kvb