2

次のコードを検討してください。

interface IFace {}

abstract class Supertype {}

class Subtype1 extends Supertype implements IFace {}
class Subtype2 extends Supertype implements IFace {}
class Subtype3 extends Supertype {}

class Foo {
    //Contains elements of Subtype1 and Subtype2
    List<IFace>     ifaceList = new ArrayList<IFace>();

    //Contains elements of Subtype1, Subtype2, and Subtype3
    List<Supertype> superList = new ArrayList<Supertype>();   

    void CopyItem() {
        superList.add( (Supertype) ifaceList.someElement() );
    }
}

サブタイプのみが実装されることがわかっている場合、IFace要素をキャストしても安全ですか? サブタイプのみが実装されることを保証することさえ可能ですか?SupertypeIFaceIFace

IFace最初のリストに特定のサブタイプのみを保持し、2 番目のリストに任意のサブタイプを許可するためのマーカー インターフェイスとして使用しようとしています。

4

4 に答える 4

2

サブタイプのみがIFaceを実装することがわかっている場合、IFace要素をスーパータイプにキャストしても安全ですか?

はい。

それを保証することさえ可能ですか?

Supertype「実装のサブクラスのみを保証することは可能ですか」という意味の場合IFace-いいえ。インターフェイスは何でも実装できます。

「キャストが成功することを保証することは可能ですか」という意味の場合-はい、キャストするinstanceof前に使用できます。

于 2012-07-04T14:06:29.380 に答える
0

サブタイプのみがIFaceを実装することがわかっている場合、IFace要素をスーパータイプにキャストしても安全ですか?

コードを知っていて、実装するすべてのクラスがIFaceのサブクラスでもあるSupertype場合、問題はありませんが、演算子のSupertype使用をいつでも確認できます。instanceof

それを保証することさえ可能ですか?

コードに次の変更を加えることを検討してください。

interface IFace {}

abstract class Supertype {}

abstract class SupertypeAndFace extends Supertype implements IFace {}

class Subtype1 extends SupertypeAndFace {}
class Subtype2 extends SupertypeAndFace {}
class Subtype3 extends Supertype {}

class Foo {
    //Contains elements of Subtype1 and Subtype2
    List<SupertypeAndFace> ifaceList = new ArrayList<SupertypeAndFace>();

    //Contains elements of Subtype1, Subtype2, and Subtype3
    List<Supertype>        superList = new ArrayList<Supertype>();   

    void CopyItem() {
        superList.add(ifaceList.someElement());
    }
}

SupertypeAndFaceそこでは、 extendsSupertypeと implementsのすべてのインスタンスを確実にするため、キャストは必要ありませんIFace

結局のところ、SupertypeIFaceが非常に関連しているため、 を実装するクラスのすべて (または少なくともほとんど) が のIFaceサブクラスでもあることがわかっているSupertype場合は、その新しい抽象化が必要になる可能性があります。

ただし、 を実装しているが のサブタイプではないifaceList他の要素も含めたい場合、この解決策は有効ではありません。その場合は、他の回答で説明されているように、演算子を使用してキャストの安全性を確認できます。IFaceSupertypeinstanceof

void CopyItem() {
    if (ifaceList.someElement() instanceof Supertype) {
        superList.add( (Supertype) ifaceList.someElement() );
    } else {
        // Throw exception if necessary
    }
}
于 2014-08-01T04:33:15.213 に答える
0

サブタイプのみがIFaceを実装することがわかっている場合、IFace要素をスーパータイプにキャストしても安全ですか?

すべての Iface 要素が Supertype も拡張することが確実にわかっている場合は、問題にはなりません。しかし、将来、これはもはや真実ではないかもしれません。

それを保証することさえ可能ですか?

はい。ClassCastException で catch を試すか、演算子でキャストする前にテストすることをお勧めしますinstanceof

void CopyItem() {
    IFace obj = ifaceList.someElement();
    if (obj instanceof Supertype) superList.add( (Supertype)obj );
    else System.err.println("WARNING: IFace object is not a Supertype.");
}
于 2012-07-04T14:21:05.963 に答える
0

最も安全な方法は、Supertype に Iface を実装させることです。それが不可能な場合は、IFace を実装するすべてのクラスがスーパータイプのサブクラスでもある限り、IFace 要素をスーパータイプにキャストしても安全です。当分の間、それが当てはまることを保証する必要がありますが、これはかなりエラーが発生しやすいです。

于 2012-07-04T14:13:22.717 に答える