为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

达令说 2023-11-10 16:10:11
有一个类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;}程序运行结果如下:问题是,如果我通过扩展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 */}
查看完整描述

2 回答

?
临摹微笑

TA贡献1982条经验 获得超2个赞

根据对您问题的评论,问题似乎是您重写了诸如 等方法setCharacteristics(...)并setSchedulingInterval(...)在超级构造函数中调用这些方法。


如果不了解更多有关系统正在做什么以及重写这些方法如何影响应用程序内部工作的信息,就很难给出您可能面临的问题的确切示例。因此,我将尝试提供一个更抽象的示例,并希望我能够传达可能出现问题的想法。


假设我们有以下课程:


class SuperType {

  protected String name;


  public SuperType(String n) {

    setName( n );

  }


  protected void setName( String n ) {

    name = n;

  }    

}


class SubType extends SuperType {

  // setting 'id' happens here

  private int id = new Random().nextInt() + 1;


  {

    // initializer block, setting 'id' could happen here       

  }


  public SubType( String n ) {

    super( n ); 

    // setting 'id' could happen here as well

  }


  @Override

  protected void setName( String n ) {

    name = n + " " + id;

  }    

}

正如您所看到的,重写了构造函数中使用的SubType方法。为什么这是一个问题?setName(...)SuperType

考虑调用时初始化发生的顺序new SubType("some name")

  • 构造函数SubType(...)调用超级构造函数,即SuperType(...)

  • 在执行构造函数之前,将创建并初始化实例。
    对于层次结构中的每个类,从上到下(从超级类型到子类型),这种情况按以下顺序发生

    • 字段按照列出的顺序排列

    • 初始化块按照列出的顺序排列

    • constructor

因此,我们的示例中有以下执行顺序(Object为了简单起见,我将保留不存在的初始化)

  • SuperType(...)构造函数(因为没有初始化块)

  • setName(...)正在被调用,但这是被覆盖的版本

  • SubType字段被初始化,设置id为随机数

  • SubType初始化块运行

  • SubType(...)构造函数运行

正如您所看到的,重写setName(...)是在id初始化之前执行的,因此该方法将看到的所有内容都将是其默认值(对于primitive 为0 int)。并且根据您的应用程序可能会出现问题 - 重写的方法可能依赖于正确初始化的一些附加变量(例如不为空),如果没有发生这种情况,实例可能仍然会被创建,但无法从您的应用程序中使用观点看法。


查看完整回答
反对 回复 2023-11-10
?
慕容3067478

TA贡献1773条经验 获得超3个赞

当你有类似的事情时:


Datacenter d = new MyDatacanter(...);

唯一可访问的方法d是超类中定义的方法Datacenter,除非您将其转换d为MyDatacenter对象:


d.yourCustomMethod(); //won't work

((MyDataCenter) d).yourCustomMethod(); //should work fine


查看完整回答
反对 回复 2023-11-10
  • 2 回答
  • 0 关注
  • 124 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信