0

I have written a class which is a base class of Class A and implements an interface of Class B.

Now my compiler is giving a wierd kind of error saying that "The return types of functiona from Class A is not compatible with return type of functiona in class B."

My Code is as below,

public class X extends A implements B
{
}

public class A
{
  public Enumeration<String> test(){}
}

public interface B
{
  public Enumeration<Object> test();
}

Now I can't understand why the compiler is giving such an error since already String is a type of an object, so what i understood is that automatic type conversion should happen in runtime because of that. Am i right? or my conceptual understanding has gone wierd on me?

kashipai
  • 149
  • 3
  • 13
  • 1
    possible duplicate of [Is `List` a subclass of `List`? Why aren't Java's generics implicitly polymorphic?](http://stackoverflow.com/questions/2745265/is-listdog-a-subclass-of-listanimal-why-arent-javas-generics-implicit) – assylias May 29 '12 at 11:51

3 Answers3

2

If you can change the definition of the interface, you can broaden it and get what you want. The return type would be Enumeration<? extends Object>

John Watts
  • 8,717
  • 1
  • 31
  • 35
1

String is a subclass of Object, but Enumeration<String> is not a subclass of Enumeration<Object>. If it were, then I could cast an Enumeration<String> to an Enumeration<Object>, then cast it to an Enumeration<Integer>, all without a warning; but when I tried to use it as an Enumeration<Integer>, I'd get ClassCastExceptions.

Note that Java arrays behave as I've described above, and this is widely considered a significant flaw in the design of the language.

Ernest Friedman-Hill
  • 80,601
  • 10
  • 150
  • 186
1

What you're trying to do is possible in Java. As Ernest stated, an Enumeration is not a subclass of Enumeration, since Java genercis lacks the concept of variance.

Anyway, you can express you intention using type wildcard. You have to change you interface this way:

public interface B
{
  public Enumeration<?> test();
}

Now your code compile fine. Just to let you know, you can also restrict your interface to some other type than Object. For example, if you have to build an interface that return Enumerations
of Number:

    class X extends A implements B
    {
    }

    class A
    {
        public Enumeration<Long> test(){return null;}
    }

    class C
    {
        public Enumeration<String> test(){return null;}
    }

    //This doesn't compile! String does not extend Number
    /*class Y extends C implements B
    {
    }*/

    interface B
    {
        public Enumeration<? extends Number> test();
    }
Andrea Parodi
  • 5,534
  • 27
  • 46
  • Our answers are similar, but Andrea's is more detailed. – John Watts May 29 '12 at 13:36
  • @John, thank you for credits; I've posted as an answer, only because in first version of your answer you did forget the " extends Object>" part, so I understood you was suggesting to use raw types – Andrea Parodi May 29 '12 at 15:01