简体   繁体   中英

Inherit multiple abstract class in java

I have a two abstract classes FlyingBird and RunningBird

public abstract FlyingBird extends Bird implements IFlyingBird {}
public abstract RunningBird extends Bird implements IRunningBird {}

Now I want to have an another abstract class that is both IRunningBird and IFlyingBird

public abstract FlyingRunningBird extends Bird implements IFlyingBird, IRunningBird {}

In this class I am duplicating all the code from FlyingBird and RunningBird
Aggregation of dependent class is not possible as both classes are abstract

The issue is if any bug fix or modification that is done on either FlyingBird or RunningBird will not reflect in FlyingRunningBird . I need to update the FlyingRunningBird too.

Is there any we can avoid this code duplication in FlyingRunningBird ? or
Use FlyingBird and RunningBird in FlyingRunningBird to avoid code duplication?

Java was designed with the problems of multiple inheritance in C++ in mind. So only single inheritance and multiple interfaces. At that time in C++ there could be ambiguity of a method that could belong to two parent classes.

To achieve your goal, the solution is to use delegating:

  • specify interfaces
  • specify implementations
  • delegate

Using an other conventional naming:

public interface Flying {
    void fly();
    double getWingSpan();
}

public class FlyingImplementation {
    public FlyingImplementation(Bird bird)
    ...
}

public interface Running {
    void run();
    double getRunningSpeed();
}

public class RunningImplementation {
    public RunningImplementation(Bird bird) {}
    ...
}

public abstract FlyingRunningBird implements Flying, Running, Bird {
    private final Flying birdFlying;
    private final Running birdRunning;

    protected FlyingRunningBird() {
        birdFlying = new FlyingImplementation(this);
        birdRunning = new RunningImplementation(this);
    }

    @Override
    public void fly() {
        birdFlying.fly();
    }

    @Override
    void run() {
        birdRunning.run();
    }
    ...
}

The common things in Bird , which also could have a base class. Flying and Running are capabilities, names adjectives, sole responsibility: flying resp. running.

Delegating to birdFlying and birdRunning makes the "multiple inheritance" explicit and is by no means less expressive.

I think there are two ways you can approach this:

  1. Move the method implementations as default methods in the corresponding interface , given that you're using Java 8+ and those methods do not need to access fields (in which case you'll need to have some accessors in your interface or reconsider your design).
  2. Favor composition over inheritance, though in this particular case this doesn't seem quite natural. Ie your FlyingRunningBird could be provided with an instance of FlyingBird and an instance of RunningBird (at construction time), and it will simply delegate the method calls for each of the interfaces to the corresponding implementation.

In your case, you may use Helper classes -> classes that do not fall anywhere in the hierarchy but have the common code to avoid duplicacy.

Otherwise, from the OO point of view -

  1. A FlyingRunningBird may not fly the same as a FlyingBird.
  2. A FlyingRunningBird may not fly the same as a RunningBird

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