超类方法返回超类对象

Superclass methods returning superclass object

我在解决方案中使用 JDOM 库。
我创建了以下 class,因为我想要添加功能(主要是 get 方法来解析来自 XML 元素的特定类型的数据)。

public class MyElement extends Element {
    // methods such as...
    public Boolean getBoolean(){

    }
}

当然,带数据的元素不是根元素,所以我想做的是:

// MyElement variable "data" has been assigned before
Boolean isTest = data.getChild("isTest").getBoolean();

问题是 getChild returns 一个 Element 对象(由 superclass 实现),它又不知道 subclass方法。

根据我在其他问题中所读到的内容,向下转换不起作用?
我想过重写 getChild 方法,但也需要一个沮丧的方法,对吗?

是否可以使用或覆盖 superclass 方法,以便返回的 Element 对象可以被视为 MyElement 对象?

我找到了 ,但前提是您也可以更改 superclass 的方法。

如果您可以将@Overrides 批注添加到方法中,并且编译器不会报错,那么即使定义了 Element.getBoolean() 也会调用您的方法。

public class MyElement extends Element {
   @Override
   public Boolean getBoolean() {
      ... whatever there was before, My element will return this ...
      return true;
   }
}

如果您不能添加@Override,那么 Element 就没有 getBoolean() 方法,因此当您添加时

data.getChild("isTest")

您将收到一个 Element,它可能恰好是 MyElement,但也可能是其他东西。虽然这不是在所有情况下都是最好的方法,但有时 downcast

是合适的
Element element = data.getChild("isTest");
Boolean boolValue;
if (element instanceof MyElement) {
   boolValue= ((MyElement)element).getBoolean();
} else {
   boolValue= Boolean.FALSE;
}

我故意不考虑实际的 Element 类型来回答,因为理解规则比理解仅适用于特定 class 的规则重要得多。

祝你好运!

是的,你可以覆盖getChild方法,但是你不能改变return类型(被覆盖方法的签名不能改变),即你可以return仅键入 Element 或其子 class,它也是 Element 类型,因为它扩展了 Element class。由于 returned subclass 被超类型接口隐藏,您需要将 returned Element 类型向下转换为您的 subclass.

Boolean isTest = ((MyElement) data.getChild("isTest")).getBoolean();

您可以编写简单的方法,自动将 Element 向下转换为您的子class 以缩短代码。

public static MyElement myElement(Element e) {
    return (MyElement) e;
}

// ...
    Boolean isTest = myElement(data.getChild("isTest")).getBoolean();
// ...

我可能会制作一个静态 class 来为 Element 保存 "extension methods"。这类似于 Integer.parseInt(String s);

Boolean isTest = MyElement.getBoolean(data.getChild("isTest"));

一个实现是

public static class MyElement {
    public static boolean getBoolean(Element e) {
        // Do your thing.
        return e.getValue() == "true" || e.getValue() == "1";
    }
}

您可以检查 Element 的实例以查看它是否为 MyElement 然后进行转换。但是只有当 Element 实际上属于该实例时,此转换才会成功。这意味着您添加了构建它并将其添加到您的文档中。

希望对您有所帮助。