简体   繁体   中英

Is it possible to overload abstract methods in an abstract Java class, but implement only one of the overloaded methods in subclass?

I have an abstract class (showing only the relevant parts) with two overloaded methods.

abstract public class Component {
    ...
    abstract protected void createPhysics();
    abstract protected void createPhysics(Comp1D[] comp1DS);
    ...
}

In the subclasses which extend this abstract class I only want to use either the one with arguments or the one without, but never both of them. For example

public class Comp1D extends Component{
    ...
    protected void createPhysics(Comp1D[] comp1Ds){
        ...
    }
}

and

public class Comp3D extends Component{
    ...
    protected void createPhysics(){
        ...
    }
}

Of course this won't compile this way since the other createPhysics method is not implemented in the subclass. My quick and dirty solution would be to implement both methods in subclasses, but the unused method would have empty body.

Is there a more elegant way to solve it in Java 8?

With abstract methods, there is not. And on a syntactical level, it would not be sound either. If one has a Component , one can call both methods. How should one know which one is implemented and which one is not?

One could define both method in the abstract class and let them throw, for example, an UnsupportedOperationException , thus forcing sublcasses to override (at least one of) those methods if they wish to not throw such an exception. This, however, seems like a workaround for another problem.

I would suggest re-evaluating the overall architecture of that section and find another solution to the problem. For example, maybe two separated classes and handler for those classes would yield a cleaner architecture.

The question is, why do you want to use an Abstract class here. What if you plan to use an interface, with default implementations. You can implement the interface and override only the required method

The idea of using abstract class is when you want to define common method signatures in the class and force sub-classes to provide implementation for such methods. From this point of view the way you are trying to implement abstract class doesn't make much sense.

You can also use abstract class to define a base type to support OO features like polymorphism and inheritance and i think this is what are you trying to do. If this is the case i suggest to declare an abstract class without abstract methods or declare an interface with default implementation for both methods and then you can override in implementation classes.

As @Turning85 pointed out, such an implementation would not make much sense.

Either you want to give your successor classes the flexibility to implement both of the methods according to their own specific needs or you want to take this complexity away from them and implement the whole logic in the abstract class, where you could have something like this:

abstract class Component() {

    protected void createDefaultPhysics() {
        //implement
    }

    abstract protected void createPhysics(Comp1D[] comp1DS);

}

and your concrete classes:

public class Comp1D extends Component{

      protected void createPhysics(Comp1D[] comp1Ds){
           if(comp1Ds == null) {
                createDefaultPhysics();
           }
      }
}

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