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用作标记界面,以仅在第一个列表中保留某些子类型,并在第二个列表中允许任何子类型。

4

4 回答 4

2

如果我知道只有子类型会实现 IFace,那么将 IFace 元素转换为 Supertype 是否安全?

是的。

甚至有可能确保这一点吗?

如果您的意思是“是否可以确保仅Supertype实现子类IFace”-否。接口可以由任何东西实现。

如果您的意思是“是否有可能确保演员成功” - 是的,您可以instanceof在演员之前使用。

于 2012-07-04T14:06:29.380 回答
0

最安全的方法是让 Supertype 实现 IFace。如果这不可能,那么只要实现 IFace 的每个类也是 Supertype 子类,就可以安全地将 IFace 元素强制转换为 Supertype。您必须确保暂时适用,这很容易出错。

于 2012-07-04T14:13:22.717 回答
0

如果我知道只有子类型会实现 IFace,那么将 IFace 元素转换为 Supertype 是否安全?

如果您确定所有 IFace 元素也扩展了 Supertype,那么这不会是一个问题。但在未来,这可能不再是真的。

甚至有可能确保这一点吗?

是的。您可以尝试在 ClassCastException 上捕获,甚至在使用运算符强制转换之前更好地对其进行测试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

如果我知道只有子类型会实现 IFace,那么将 IFace 元素转换为 Supertype 是否安全?

如果你知道你的代码,并且每个实现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());
    }
}

在那里,不需要强制转换,因为您确保SupertypeAndFaceextendsSupertype和 implements的每个实例IFace

毕竟,如果SupertypeIFace如此相关以至于您知道所有(或至少大多数)实现IFace的类也是 的子类Supertype,那么您可能需要那个新的抽象。

但是,如果您还想ifaceList包含实现 的其他元素IFace,但不是 的子类型Supertype,则此解决方案无效。如果是这种情况,您可以使用instanceof操作员检查演员表的安全性,如其他答案所述。

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