告诉Java编译器在运行时可以访问该字段吗?

时间:2015-04-11 13:40:45

标签: java inheritance casting compiler-errors polymorphism

我有3个光源类(X,Y和Z)继承自更一般的光源类。

3个班级中的2个,有一个“位置”字段。 (X和Y)

在其他方法中,我浏览某个列表的所有光源,然后检查当前光源是否是Z的实例。 如果不是,我想访问X(或Y)的“位置”字段而不转换当前实例。 但编译器不会让我,我想告诉它,在运行时,可以访问这个字段。

实际上在两种情况下都不会让我在没有强制转换的情况下访问该字段,尽管在运行时它不会破坏。

是的,我可以写几行来处理这个问题,但我出于好奇而问这个问题,因为我喜欢极简主义编码。

for (Light light : lights) {
    Vec vector;
    if (light instanceof DirLight) vector = light.direction;
    else vector = new Vec(intersectionPoint, light.position);
}

3 个答案:

答案 0 :(得分:2)

通常需要强制转换是代码设计不良的标志。在你的情况下,我可以想象很多方法来编写更清晰的代码:

1. Light的每个实现都可以有一个返回Vector的方法。

public abstract Vector getVector();

2.如果拥有这样的方法不对,你可以像这样实现Visitor-Pattern

灯:

public abstract void visit(Visitor visitor);

新界面:

public interface Visitor {
     public void visit(Light1 light);
     public void visit(Light2 light);
     public void visit(Light3 light);
}

用法:

light.visit(new Visitor() { ... });

答案 1 :(得分:1)

Java是强类型的。您正在尝试访问DirLight上但不在Light上的成员,并且需要转换。没有办法解决它。

答案 2 :(得分:0)

没有办法绕过它。您可以使用反射来获得该字段。但是,这通常只是出于非常强烈的原因而使用,而不是出于您在问题中给出的原因。当然,您应该只是对对象执行强制转换。

但是这里是你如何得到一个物体的任何一个领域。

    // initialize o
    for (Field field : o.getClass().getDeclaredFields()) {
        Object value = field.get(o); 
        if (value != null) {
            System.out.println(field.getName() + "=" + value);
        }
    }