简体   繁体   中英

Superclass methods returning superclass object

I'm using the JDOM library in a solution.
I have created the following class because I want to have added capabilities (mostly get methods to parse specific types of data from XML elements).

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

    }
}

Of course, the elements with data are not the root element, so what I want do is this:

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

The problem is that getChild returns an Element object (as implemented by the superclass), which in turn does not know the subclass method.

From what I've read in other questions, downcasting wouldn't work?
I have thought of overriding the getChild method but there a downcast would be needed too, right?

Is it possible to use or override the superclass methods so that returned Element objects can be seen as MyElement objects?

I have found this question but that assumes you can alter the superclass's methods too.

If you can add the @Overrides annotation to the method, and the compiler doesn't complain, your method will be called even if an Element.getBoolean() is defined.

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

If you cannot add the @Override, then Element doesn't have a getBoolean() method, and as such when you do

data.getChild("isTest")

you will receive an Element that may happen to be a MyElement , but it may be something else. While it is not the best approach under all circumstances, sometimes it is appropriate to downcast

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

I've deliberately answered without considering the actual Element type, as it is far more important to understand the rules than to understand the rules as they apply to only a specific class.

Good Luck!

Yes, you can override getChild method, but you can not change return type (signature of the overriden method can not be changed), that is, you can return only type Element or it's subclass, which is also of Element type, since it extends Element class. Since returned subclass is hidden by super type interface, you would need to down cast returned Element type to your subclass.

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

You can write simple method that will automatically downcast Element into your subclass to shortener code.

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

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

I would probably make a static class to hold "extension methods" for Element. This is similar to Integer.parseInt(String s);

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

An implementation would be

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

You could check the instance of Element to see if it is MyElement and then cast it. But this cast will only succeed if the Element is actually of that instance. Meaning that you added constructed it and added it to your Document.

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM