2012-10-13 349 views
2

這段代碼不是我的,我需要對它進行一些改進,但是我陷入了這個問題。Java從抽象類訪問子類的方法/變量

我有一個抽象類「CallNode」和很多子類,其中一個是「Call」。 「Checker」類正在攔截未接來電,但將其作爲CallNode返回。我的問題是,我需要獲得此通話的ID,但我無法通過CallNode訪問它。

你有什麼建議可以解決這個問題嗎?

我讓你的代碼,這樣就可以更好地理解這個問題:

public abstract class CallNode { 
    public abstract CallNode hasMissingCall(); 
} 

public class Call extends CallNode { 
    public int id; 

    // Simplification of method 
    public CallNode hasMissingCall() { 
     if (true) 
      return this; 
     // ... 
    } 
} 

public class Checker{ 
    private static CallNode rootExpected; 

    CallNode missing = rootExpected.hasMissingCall(); 

    System.out.println(missing.id); // THE PROBLEM!!! 
} 

感謝的提前!

+1

'公共抽象CallNode hasMissingCall();',聽起來像它應該返回一個布爾值。特別糟糕。 –

回答

3

定義模板方法在抽象類返回ID:

public abstract class CallNode { 
    public abstract CallNode hasMissingCall(); 

    public abstract int getId(); 
} 

讓子類實現:

public class Call extends CallNode { 
    public int id; 

    // Simplification of method 
    public CallNode hasMissingCall() { 
     if (true) 
      return this; 
     // ... 
    } 
    public int getId() 
    { 
     return this.id; 
    } 
} 

這是一個選項。就我個人而言,我將在CallNode類中向上移動id字段,因爲我認爲它應該是唯一的,並由所有子類共享。

+0

謝謝海森伯格。我試圖避免很多課程的變化,但這確實是需要的!我將把「id」字段移動到「CallNode」並創建一個抽象的「getID()」。 – mariofalcao

+0

加上最後一個建議,名稱Heisenbug。 – rjdamore

2

您應該never directly access your fields

一般而言,fields應宣佈爲private,您應該有public accessor方法來訪問它們。

如果您可以修改您的班級,則可以在abstract CallNode班級和Call班級中添加方法getId()。並且在Call類中,此方法返回您的this.id。這將爲你完成這項工作。

所以,這種方法添加到您的Call類: -

public int getId() { 
    return this.id; 
} 

讓這個方法是abstractAbstract類。

public abstract class CallNode { 
    public abstract CallNode hasMissingCall(); 
    public abstract int getId(); 
} 

而且使用調用它: -

missing.getId(); 

這將調用你的CallgetId()

此代碼是不是我的,我需要一些改進,給它添加,

PS: -一個改進你真的需要補充的是,改變hasMissingCallgetMissingCall,因爲它正在恢復你一個missed call。始終在您的代碼中關注naming conventions
還記得,你不爲自己編寫代碼,但你寫他們爲他人使用和維護。

+0

感謝您的提示,Rohit。我將所有的字段都聲明爲「私有」,我提供的代碼是對真實代碼的簡化,以便可以更快地識別問題。我將使用您提出的解決方案。關於方法術語,我承認這不是最好的,但它不是我的代碼。再次感謝提示。 – mariofalcao

+0

@MárioFalcãoCastro不客氣.. :) –

1

你可以垂下來Call

System.out.println(((Call) missing).id); 

也就是說,如果你不能改變其他類的,如果你知道missing將是Call一個實例。

+0

謝謝,弗拉德!但我現在正在驗證,我不能保證「缺失」將是「調用」的一個實例,它可以是「CallNode」的另一個子類的實例。 – mariofalcao

0

您可以在CallNode中指定absract方法getId()並在子節點中實現它。然後你在Checker中訪問它。

public abstract class CallNode { 
    public abstract CallNode hasMissingCall(); 
    public abstract int getId(); 
} 

public class Checker{ 
    private static CallNode rootExpected; 

    CallNode missing = rootExpected.hasMissingCall(); 

    System.out.println(missing.getId()); 
} 

public class Call extends CallNode { 
    public int id; // better set private modifier 
    public int getId() { 
     return id; 
    } 
    ... 
} 
+0

謝謝你,安東。我會用這種方法。 – mariofalcao

相關問題