[英]The program won't work using subclass instead of superclass
有一個名為Datacenter
的 class ,其中的構造函數是:
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());
}
我們使用這個 class 在程序中制作數據中心:
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
class 來定義自己的數據中心,則該程序將無法運行。 我將MyDatacenter
class 定義如下:
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 分配給任何數據中心:
我什至無法將創建的Datacenter
實例轉換為MyDatacenter
。
當你有類似的東西時:
Datacenter d = new MyDatacanter(...);
d
可以訪問的唯一方法是在超類Datacenter
中定義的方法,除非您將d
轉換為MyDatacenter
object:
d.yourCustomMethod(); //won't work
((MyDataCenter) d).yourCustomMethod(); //should work fine
根據對您問題的評論,問題似乎是您覆蓋了 setCharacteristics(... setCharacteristics(...)
、 setSchedulingInterval(...)
等方法並在超級構造函數中調用這些方法。
如果不了解更多關於您的系統正在做什么以及重寫這些方法如何影響應用程序的內部工作,就很難給出您可能面臨的問題的確切示例。 因此,我將嘗試提供一個更抽象的示例,並希望我能傳達 go 可能出錯的想法。
假設我們有以下類:
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(...)
調用超級構造函數,即SuperType(...)
因此,我們在示例中具有以下執行順序(為簡單起見,我將留下Object
和不存在的初始化)
SuperType(...)
構造函數(因為沒有初始化塊)setName(...)
但這是被覆蓋的版本SubType
字段,將id
設置為隨機數SubType
初始化程序塊運行SubType(...)
構造函數運行如您所見,覆蓋的setName(...)
在id
初始化之前執行,因此所有該方法將看到的將是其默認值(原始int
為 0)。 並且取決於您的應用程序,這可能是問題 - 被覆蓋的方法可能依賴於一些被正確初始化的附加變量(例如,不為空),如果沒有發生這種情況,實例可能仍然被創建但不能從您的應用程序中使用觀點看法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.