Avoid casting in inherited java-classes

前端 未结 7 1953
执念已碎
执念已碎 2021-02-14 17:56

I have a class:

class MyClass {

  public MyClass getParent() { ... }

  public MyClass[] getChildren() { ... }

  ....

}

and a subclass

相关标签:
7条回答
  • 2021-02-14 18:20

    Beginning with Java 5.0, you can override methods with covariant return types, i.e. you can override a method to return a subclass parent class. (see Covariant return type in Java):

    public class MySubClass extends MyClass {
    
      @Override
      public MySubClass getParent() {
        return (MySubClass) super.getParent();
      }
    
      @Override
      public MySubClass[] getChildren() {
        return (MySubClass[]) super.getChildren();
      }
    
      public String getId() {
        ...
      }
    }
    

    You can then call new MySubClass().getChildren()[0].getId().

    Of course this will only work if MySubClass always has MySubClass instances as parent and/or children

    0 讨论(0)
  • 2021-02-14 18:32

    Maybe using generics (http://docs.oracle.com/javase/tutorial/extra/generics/index.html)

    You should have something like this:

    public class MyClass<T extends MyClass> {
    
        public T getParent() { return null; }
    
        public MyClass[] getChildren() {
            return null;
        }
    
        public static void main(String[] args) {
            MyClass<MySubClass> o = new MySubClass();
            o.getParent().getId();
        }
    }
    
    class MySubClass extends MyClass<MySubClass> {
    
        public String getId() {
            return "";
        }
    }
    
    0 讨论(0)
  • 2021-02-14 18:32

    Yes, assuming that you know that the parent and children of a MySubClass will always be of type MySubClass.

    In that case you could just narrow the return types in MySubClass and do the casting there:

    MySubClass extends MyClass() {
        @Overrides
        public MySubClass getParent() { return (MySubclass) super.getParent(); }
    
        @Overrides
        public MySubClass[] getChildren() { return (MySubclass[]) super.getChildren(); }
    
        public String getId() { }
    
        ...
    }
    
    0 讨论(0)
  • 2021-02-14 18:32

    Depending on what you are actually trying to do, either make your base class abstract and add getId():

    abstract class MyClass() {
        public MyClass getParent() { ... }
        public MyClass[] getChildren() { ... }
        public String getId();
        ....
    }
    
    MySubClass extends MyClass() {
        @Overrides
        public String getId() { }
        ...
    }
    

    Alternatively, depending on your requirements, implement getId() in your base class:

    class MyClass() {
        public MyClass getParent() { ... }
        public MyClass[] getChildren() { ... }
        public String getId() { }
        ....
    }
    
    MySubClass extends MyClass() {
        ...
    }
    
    0 讨论(0)
  • 2021-02-14 18:34

    You can use the self-type pattern:

    class MyClass<T extends MyClass<T>> { 
      public T getParent() { ... }
      public List<T> getChildren() { ... }  // you can use an array here too, but don't :)
    }
    
    class MySubclass extends MyClass<MySubclass> {
      public String getId() { ... }
    }
    

    You can implement your getParent and getChildren methods as desired, declare fields in MyClass that hold T references and know that they behave at least as MyClass references, et cetera. And if you call getParent or getChildren on a MySubClass, you can use the return values as MySubClass instances with no casts anywhere.

    The primary disadvantage of this approach is that people who haven't seen it before tend to get pretty confused.

    0 讨论(0)
  • 2021-02-14 18:40

    Add the method getId to the super class as well ie. MyClass.

    Any subclasses can still override and have their own implementation. If you are scared of subclasses not overriding getId,then throw an exception from the super class from getId.

    Th erotically, getID is some thing that is applicable for All Class and hence can be added to super.

    0 讨论(0)
提交回复
热议问题