在子类/接口和超类之间进行转换

时间:2012-07-04 14:04:00

标签: java class interface casting

请考虑以下代码:

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() );
    }
}

如果我知道只有Subtypes会实现IFace,那么将Supertype元素转换为IFace是否安全?甚至可以确保只有Subtypes实现IFace

我正在尝试使用IFace作为标记接口,仅在第一个列表中保留某些子类型,并允许第二个列表中的任何子类型。

4 个答案:

答案 0 :(得分:2)

  

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

  

甚至可以确保吗?

如果您的意思是“是否可以确保只有Supertype的子类实现IFace” - 否。接口可以通过任何方式实现。

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

  

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

如果您确定所有IFace元素也扩展了Supertype,那么它就不会成为问题。但在将来,这可能不再适用。

  

甚至可以确保吗?

是。您可以尝试捕获ClassCastException,或者在使用operator 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.");
}

答案 3 :(得分:0)

  

如果我只知道那么将IFace元素强制转换为Supertype是否安全   子类型将实施IFace?

如果您知道自己的代码,并且实现IFace的每个类也是Supertype的子类,则没有问题,但您始终可以使用{{Supertype检查instanceof 1}}运算符,确定。

  

甚至可以确保吗?

请考虑对您的代码进行以下修改:

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的每个实例都延伸Supertype并实现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
    }
}