0

クラス A の基本クラスであり、クラス B のインターフェースを実装するクラスを作成しました。

現在、私のコンパイラは、「クラス A からの functiona の戻り値の型は、クラス B の functiona の戻り値の型と互換性がありません」という奇妙な種類のエラーを出しています。

私のコードは以下の通りです、

public class X extends A implements B
{
}

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

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

String はすでにオブジェクトの型であるため、コンパイラがこのようなエラーを出す理由がわかりません。そのため、実行時に自動型変換が発生する必要があることを理解しました。私は正しいですか?または、私の概念的な理解が私に奇妙になりましたか?

4

3 に答える 3

2

インターフェイスの定義を変更できる場合は、それを広げて、必要なものを取得できます。戻り値の型は次のようになりますEnumeration<? extends Object>

于 2012-05-29T11:56:49.083 に答える
1

Stringは のサブクラスですが、 のサブクラスでObjectはありEnumeration<String>ませEnumeration<Object>。もしそうなら、私は an を an にキャストしてから、それを an にキャストすることができEnumeration<String>ますEnumeration<Object>Enumeration<Integer>すべて警告なしです。しかし、それを として使用しようとすると、Enumeration<Integer>が得られClassCastExceptionます。

Java 配列は上で説明したように動作することに注意してください。これは、言語の設計における重大な欠陥であると広く考えられています。

于 2012-05-29T11:49:11.880 に答える
1

あなたがやろうとしていることはJavaで可能です。Ernest が述べたように、列挙型は列挙型のサブクラスではありません。Java ジェネリックには分散の概念がないためです。

とにかく、タイプワイルドカードを使用して意図を表現できます。この方法でインターフェイスを変更する必要があります。

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

これで、コードが正常にコンパイルされます。お知らせするために、インターフェイスを Object 以外のタイプに制限することもできます。たとえば、
数値の列挙を返すインターフェイスを構築する必要がある場合:

    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();
    }
于 2012-05-29T11:59:12.437 に答える