gpt4 book ai didi

java - 该程序无法使用子类而不是父类(super class)来运行

转载 作者:行者123 更新时间:2023-12-02 09:24:13 24 4
gpt4 key购买 nike

有一个名为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;
}

程序运行结果如下:

enter image description here

问题是,如果我通过扩展 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 */

}

因此,如果我将 createDatacenter() 方法的返回类型从 Datacenter 更改为 MyDatacenter,程序将无法工作。

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

/* No changes */

MyDatacenter datacenter = null;
try {
datacenter = new MyDatacenter(name, characteristics,
new VmAllocationPolicySimple(hostList), myHarddriveList, 0);
} catch (Exception e) {
System.out.println("Error: " + e);
}

return datacenter;
}

不会将任何 cloudlet 分配给任何数据中心:

enter image description here

我什至无法将创建的 Datacenter 实例强制转换为 MyDatacenter

最佳答案

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

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

假设我们有以下类:

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 重写了 SuperType 构造函数中使用的 setName(...) 方法。为什么这是一个问题?

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

  • 构造函数 SubType(...) 调用 super 构造函数,即 SuperType(...)
  • 在执行构造函数之前,将创建并初始化实例。
    对于层次结构中的每个类,从上到下(从 super 类型到子类型),这按以下顺序发生
    • 字段按列出的顺序排列
    • 初始化 block 按照列出的顺序排列
    • 构造函数

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

  • SuperType(...) 构造函数(因为没有初始化 block )
  • setName(...) 正在被调用,但这是覆盖的版本
  • SubType 字段已初始化,将 id 设置为随机数
  • SubType 初始化 block 运行
  • SubType(...) 构造函数运行

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

关于java - 该程序无法使用子类而不是父类(super class)来运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58451918/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com