-1

I'm trying to understand why this code won't compile.
I've got a class implementing an interface. The last method won't compile for some reason.

It will not simply allow me to cast the set as a set, but does allow it to return the single object fine.

Can someone please explain to me why this is? thanks.

public class Testing2 {

    public SortedSet<ITesting> iTests = new TreeSet<ITesting>();
    public SortedSet<Testing> tests = new TreeSet<Testing>();

    public ITesting iTest = null;
    public ITesting test = new Testing();

    // Returns the implementing class as expected
    public ITesting getITesting(){
        return this.test;
    }

    // This method will not compile
    // Type mismatch: cannot convert from SortedSet<Testing> to SortedSet<ITesting>
    public SortedSet<ITesting> getITests(){
        return this.tests;
    }

}
benzonico
  • 10,635
  • 5
  • 42
  • 50
Marley
  • 3
  • 1

4 Answers4

6

Simply, a SortedSet<Testing> is not a SortedSet<ITesting>. For example:

SortedSet<Testing> testing = new TreeMap<Testing>();
// Imagine if this compiled...
SortedSet<ITesting> broken = testing;
broken.add(new SomeOtherImplementationOfITesting());

Now your SortedSet<Testing> would contain an element which isn't a Testing. That would be bad.

What you can do is this:

SortedSet<? extends ITesting> working = testing;

... because then you can only get values out of the set.

So this should work:

public SortedSet<? extends ITesting> getITests(){
    return this.tests;
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
1

Assuming ITesting is a super type of Testing. Generic types are not polymorphic.Thus SortedSet<ITesting> is not a super type of SortedSet<Testing>.Polymorphism simply doesn't apply for generic types. you probably need to use wildcards with lowerbounds ? extends ITesting as your return type.

public SortedSet<? extends ITesting> getITests(){
    return this.tests;
} 
PermGenError
  • 45,977
  • 8
  • 87
  • 106
0

You have a typo in your declartion:

public SortedSet<Testing> tests = new TreeSet<Testing>();

Should be ITesting there if you want the method to return an ITesting, or you need the method to return:

SortedSet<Testing>
Michael
  • 6,141
  • 2
  • 20
  • 21
0

I think you want this instead:

public SortedSet<Testing> getTests(){
    return this.tests;
}

Right now you're trying to return tests, which is declared as a SortedSet<Testing> and not SortedSet<ITesting>.

thegrinner
  • 11,546
  • 5
  • 41
  • 64