0

我正在使用 Java 开发库存程序。我将库存中的每个对象都存储为每个位置的相关DefaultListModel类类型;JList例如,如果我在“Dorm”位置有一个名为“Mulan”的视频和一个名为“Ball”的通用事物,在JList名为“Dorm”中,“Mulan”将是一个实例,video“Ball”将是一个实例的thing。所有的类都继承自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());

...它返回class videoor class thing,具体取决于选择的是“Ball”还是“Mulan”,所以我知道 java 知道它是什么类。

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

4

2 回答 2

0

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

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

但在我看来,我宁愿在你的事物和视频之上再添加 1 级类,并为事物和视频提供一个通用的方法。

于 2013-03-11T07:30:07.530 回答
0

这里的问题在于您的面向对象设计。什么样的方法是“methodInVideoOrThing()”?如果这是所有事物(包括视频)共有的方法,那么它属于 Thing。如果它是特定于视频的方法,那么它属于 Video。

在第一种情况下(Thing 的方法),您只需将 JList 中的值转换为 Thing 即可:

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

在第二种情况下(视频方法),您遇到了您描述的问题,即必须区分不同类别的事物,如视频、水果和服装。我想在这种情况下我会做的是创建单独的类来处理每个类别并根据其类别将对象传递给它,一个简单的例子:

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);
        }
    }
}

这可以做得更好一点,例如使用枚举作为类别而不是类,使用泛型来键入处理程序并将任何常见行为(如类型检查)提取到抽象类中,但这就是它的要点。

于 2013-03-11T09:09:37.807 回答