簡體   English   中英

從存儲為超類Java的子類訪問方法(向下轉換?)

[英]Accessing methods from subclass stored as superclass Java (downcasting?)

我正在使用Java開發清單程序。 我將清單中的每個對象存儲為每個位置的DefaultListModelJList的相關類類型; 例如,如果我在“宿舍”位置有一個名為“ Mulan”的視頻和一個名為“ Ball”的通用對象,則在JList “ Dorm”中,“ Mulan”將是video一個實例,而“ Ball”將是thing一個實例。 所有的類都是從事物繼承的。

我正在嘗試做這樣的事情...

Dorm.getSelectedValue().methodInVideoOrThing;

...但是當我嘗試時,它說:

error: cannot find symbol
      Dorm.getSelectedValue().methodInVideoOrThing();
                             ^
symbol:   method methodInVideoOrThing()
location: class Object

因為DefaultListModel將每個對象存儲在通用object變量中,所以我無法訪問所創建的任何類的方法。 我試過了

class c = Dorm.getSelectedValue().getClass();
c A = (c) Dorm.getSelectedValue();
A.methodInC;

...但是它返回以下錯誤:

error: cannot find symbol
      c A = (c) Dorm.getSelectedValue();
      ^
symbol: class c

error: cannot find symbol
      c A = (c) Dorm.getSelectedValue();
             ^
2 errors
symbol: class c

我知道我可以使用isInstanceOf循環遍歷所有類,並逐個案例進行向下轉換,但這將非常乏味。 另外,當我這樣做時...

System.out.println(Dorm.getSelectedValue().getClass());

...根據選擇的是“ Ball”還是“ Mulan”,它返回class videoclass thing ,所以我知道java知道它是什么類。

因此,當該子類存儲為類型為object的變量而無需向下轉換時,有什么方法可以訪問該子類的方法? 還是可以通過向下轉換來做到這一點,而我只是做錯了?

因此,除了向下轉換之外,沒有辦法使用超類型的子類型方法。 這樣更好,您可以設置一個if-else階梯

if (o instanceof Type1)
{
((Type1)0)MethodOfType1
}
else if
{
...
}

但是我認為,我寧願在您的事物和視頻之上再增加一個級別的類,並為事物和視頻提供通用的方法。

這里的問題與您的面向對象設計有關。 methodInVideoOrThing()是什么方法? 如果這是所有事物(包括視頻)共有的方法,則它屬於Thing。 如果是視頻特定的方法,則它屬於視頻。

在第一種情況下(Thing的方法),您可以將值從JList強制轉換為Thing,然后完成:

Thing selectedThing = (Thing) dorm.getSelectedValue();
selectedThing.methodInThing();

在第二種情況下(視頻方法),您遇到的問題是必須區分不同類別的事物,例如視頻,水果和服裝。 在這種情況下,我想做的是創建單獨的類來處理每個類別,並根據其類別將Object傳遞給它,這是一個簡單的示例:

public interface Handler {
    public Class getCategory();
    public void handle(Thing item);
}

public class VideoHandler implements Handler {
    public Class getCategory() {
        return Video.class;
    }

    public void handle(Thing item) {
        if (!item instanceof getCategory()) {
            throw new IllegalArgumentException("Wrong category - can only handle Video");
        }
        Video video = (Video) item;
        // do video-things            
    }        
}

在調用類中,您需要根據類別選擇正確的處理程序:

private void init() {
    List<Handler> handlers = new ArrayList<Handler>();
    handlers.add(new VideoHandler());
    // add other handlers
}

public void someMethod(Jlist dorm) { 
    Object item = dorm.getSelectedValue();
    for(Handler handler : handlers) {
        if (item instanceof handler.getCategory()) {
            // optionally catch IllegalArgumentException here 
            handler.handle(item);
        }
    }
}

這可以做得更好一些,例如,使用枚舉作為Category代替類,使用泛型鍵入Handler並將任何常見行為(如類型檢查)提取到抽象類中,但這是它的要旨。

暫無
暫無

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

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