在 java 中继承多个摘要 class

Inherit multiple abstract class in java

我有两个 abstract classes FlyingBirdRunningBird

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

现在我想要另一个摘要 class 既是 IRunningBird 又是 IFlyingBird

public abstract FlyingRunningBird extends Bird implements IFlyingBird, IRunningBird {}

在这个 class 中,我复制了 FlyingBirdRunningBird
中的所有代码 依赖 class 的聚合是不可能的,因为两个 class 都是抽象的

问题是在 FlyingBirdRunningBird 上完成的任何错误修复或修改不会反映在 FlyingRunningBird 中。我也需要更新 FlyingRunningBird

有什么方法可以避免 FlyingRunningBird 中的代码重复?或
FlyingRunningBird中使用FlyingBirdRunningBird来避免代码重复?

我认为有两种方法可以解决这个问题:

  1. 将方法实现作为 default 方法移动到相应的 interface 中,前提是您使用的是 Java 8+,并且这些方法不需要访问字段(其中如果您需要在界面中使用一些访问器或重新考虑您的设计)。
  2. 组合优于继承,尽管在这种特殊情况下这似乎不太自然。 IE。您的 FlyingRunningBird 可以提供 FlyingBird 的实例和 RunningBird 的实例(在构建时),它只会将每个接口的方法调用委托给相应的实现.

在您的情况下,您可以使用 Helper 类 -> 类,它不属于层次结构中的任何位置,但具有通用代码以避免重复。

否则,从OO的角度来看-

  1. FlyingRunningBird 可能不会像 FlyingBird 那样飞。
  2. FlyingRunningBird 可能不会像 RunningBird 那样飞

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.

要实现您的目标,解决方案是使用委派:

  • 指定接口
  • 指定实现
  • 代表

使用其他约定俗成的命名方式:

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

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

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

public class RunningImplementation implements Running {
    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();
    }
    ...
}

Bird中的常见事物,也可能有基础class。 FlyingRunning 是能力,名称形容词,唯一责任:飞行 resp。 运行.

委派给 birdFlyingbirdRunning 使“多重继承”显式 并且绝不会降低表达能力。