簡體   English   中英

該程序無法使用子類而不是超類工作

[英]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(...)
  • 在執行構造函數之前,將創建並初始化實例。
    對於層次結構中的每個 class,從上到下(超級到子類型)按以下順序發生這種情況
    • 字段按列出的順序排列
    • 初始化塊按它們列出的順序
    • 構造函數

因此,我們在示例中具有以下執行順序(為簡單起見,我將留下Object和不存在的初始化)

  • SuperType(...)構造函數(因為沒有初始化塊)
  • 正在調用setName(...)但這是被覆蓋的版本
  • 初始化SubType字段,將id設置為隨機數
  • SubType初始化程序塊運行
  • SubType(...)構造函數運行

如您所見,覆蓋的setName(...)id初始化之前執行,因此所有該方法將看到的將是其默認值(原始int為 0)。 並且取決於您的應用程序,這可能是問題 - 被覆蓋的方法可能依賴於一些被正確初始化的附加變量(例如,不為空),如果沒有發生這種情況,實例可能仍然被創建但不能從您的應用程序中使用觀點看法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM