该程序无法使用子类而不是超类来运行

有一个类Datacenter,其构造函数是:


public Datacenter(

        String name,

        DatacenterCharacteristics characteristics,

        VmAllocationPolicy vmAllocationPolicy,

        List<Storage> storageList,

        double schedulingInterval) throws Exception {

    super(name);


    setCharacteristics(characteristics);

    setVmAllocationPolicy(vmAllocationPolicy);

    setLastProcessTime(0.0);

    setStorageList(storageList);

    setVmList(new ArrayList<Vm>());

    setSchedulingInterval(schedulingInterval);


    for (Host host : getCharacteristics().getHostList()) {

        host.setDatacenter(this);

    }


    // If this resource doesn't have any PEs then no useful at all

    if (getCharacteristics().getNumberOfPes() == 0) {

                throw new Exception(super.getName()

                    + " : Error - this entity has no PEs. Therefore, can't process any Cloudlets.");

    }


    // stores id of this class

    getCharacteristics().setId(super.getId());

}

我们使用这个类在程序中创建数据中心:


private static Datacenter createDatacenter(String name, LinkedList myHarddriveList, double timeZone) {


    /* Additional codes like defining Hots */


    Datacenter datacenter = null;

    try {

        datacenter = new Datacenter(name, characteristics, 

                            new VmAllocationPolicySimple(hostList), myHarddriveList, 0);

    } catch (Exception e) {

                System.out.println("Error: " + e);

    }


    return datacenter;

}

程序运行结果如下:

https://img1.sycdn.imooc.com/654de5e80001128107730146.jpg

问题是,如果我通过扩展Datacenter类来定义自己的数据中心,程序将无法工作。我将MyDatacenter类定义如下:


public class MyDatacenter extends Datacenter{


    /* My own variables */


    public MyDatacenter(String name, 

           DatacenterCharacteristics characteristics, 

           VmAllocationPolicy vmAllocationPolicy,

           List<Storage> storageList, 

           double schedulingInterval) throws Exception {

        super(name, 

                characteristics, 

                vmAllocationPolicy,

                storageList, 

                schedulingInterval);

    }


    /* My own mwthods */


}

达令说
浏览 125回答 2
2回答

临摹微笑

根据对您问题的评论,问题似乎是您重写了诸如 等方法setCharacteristics(...)并setSchedulingInterval(...)在超级构造函数中调用这些方法。如果不了解更多有关系统正在做什么以及重写这些方法如何影响应用程序内部工作的信息,就很难给出您可能面临的问题的确切示例。因此,我将尝试提供一个更抽象的示例,并希望我能够传达可能出现问题的想法。假设我们有以下课程:class SuperType {&nbsp; protected String name;&nbsp; public SuperType(String n) {&nbsp; &nbsp; setName( n );&nbsp; }&nbsp; protected void setName( String n ) {&nbsp; &nbsp; name = n;&nbsp; }&nbsp; &nbsp;&nbsp;}class SubType extends SuperType {&nbsp; // setting 'id' happens here&nbsp; private int id = new Random().nextInt() + 1;&nbsp; {&nbsp; &nbsp; // initializer block, setting 'id' could happen here&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; }&nbsp; public SubType( String n ) {&nbsp; &nbsp; super( n );&nbsp;&nbsp; &nbsp; // setting 'id' could happen here as well&nbsp; }&nbsp; @Override&nbsp; protected void setName( String n ) {&nbsp; &nbsp; name = n + " " + id;&nbsp; }&nbsp; &nbsp;&nbsp;}正如您所看到的,重写了构造函数中使用的SubType方法。为什么这是一个问题?setName(...)SuperType考虑调用时初始化发生的顺序new SubType("some name"):构造函数SubType(...)调用超级构造函数,即SuperType(...)在执行构造函数之前,将创建并初始化实例。对于层次结构中的每个类,从上到下(从超级类型到子类型),这种情况按以下顺序发生字段按照列出的顺序排列初始化块按照列出的顺序排列constructor因此,我们的示例中有以下执行顺序(Object为了简单起见,我将保留不存在的初始化)SuperType(...)构造函数(因为没有初始化块)setName(...)正在被调用,但这是被覆盖的版本SubType字段被初始化,设置id为随机数SubType初始化块运行SubType(...)构造函数运行正如您所看到的,重写setName(...)是在id初始化之前执行的,因此该方法将看到的所有内容都将是其默认值(对于primitive 为0&nbsp;int)。并且根据您的应用程序可能会出现问题 - 重写的方法可能依赖于正确初始化的一些附加变量(例如不为空),如果没有发生这种情况,实例可能仍然会被创建,但无法从您的应用程序中使用观点看法。

慕容3067478

当你有类似的事情时:Datacenter d = new MyDatacanter(...);唯一可访问的方法d是超类中定义的方法Datacenter,除非您将其转换d为MyDatacenter对象:d.yourCustomMethod(); //won't work((MyDataCenter) d).yourCustomMethod(); //should work fine
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java