从子类访问存储为超类Java的方法(向下转换?)

时间:2013-03-11 06:17:58

标签: java class subclass jlist downcast

我正在使用Java编写库存程序。我将库存中的每个对象存储为DefaultListModelJList中的每个位置的相关类类型;例如,如果我在“Dorm”位置有一个名为“Mulan”的视频和一个名为“Ball”的通用名称,在名为“Dorm”的JList中,“Mulan”将是{{1 }和“Ball”将是video的一个实例。所有类都继承自thing。

我正在尝试这样做......

thing

...但是当我尝试它时,它说:

Dorm.getSelectedValue().methodInVideoOrThing;

因为DefaultListModel将每个对象存储在通用error: cannot find symbol Dorm.getSelectedValue().methodInVideoOrThing(); ^ symbol: method methodInVideoOrThing() location: class Object 变量中,所以我无法访问我所创建的任何类的方法。我试过这个......

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()); class video,具体取决于是选择“Ball”还是“Mulan”,所以我知道java知道它是什么类。

那么,有什么方法可以访问子类的方法,当该子类存储为object类型的变量时,没有向下转换?或者有没有办法通过向下转换来做到这一点,我只是做错了?

2 个答案:

答案 0 :(得分:0)

因此,除了向下转换之外,没有办法使用超类型的子类型方法。 所以你可以设置一个if-else梯子

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

但在我看来,我宁愿在你的东西上面增加1级以上的课程。视频,并为事物和视频提供通用方法。

答案 1 :(得分:0)

这里的问题在于您的面向对象设计。什么样的方法是“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并将任何常见行为(如类型检查)提取到抽象类中,但这是要点它