在 java 中继承多个摘要 class
Inherit multiple abstract class in java
我有两个 abstract
classes FlyingBird
和 RunningBird
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 中,我复制了 FlyingBird
和 RunningBird
中的所有代码
依赖 class 的聚合是不可能的,因为两个 class 都是抽象的
问题是在 FlyingBird
或 RunningBird
上完成的任何错误修复或修改不会反映在 FlyingRunningBird
中。我也需要更新 FlyingRunningBird
。
有什么方法可以避免 FlyingRunningBird
中的代码重复?或
在FlyingRunningBird
中使用FlyingBird
和RunningBird
来避免代码重复?
我认为有两种方法可以解决这个问题:
- 将方法实现作为
default
方法移动到相应的 interface
中,前提是您使用的是 Java 8+,并且这些方法不需要访问字段(其中如果您需要在界面中使用一些访问器或重新考虑您的设计)。
- 组合优于继承,尽管在这种特殊情况下这似乎不太自然。 IE。您的
FlyingRunningBird
可以提供 FlyingBird
的实例和 RunningBird
的实例(在构建时),它只会将每个接口的方法调用委托给相应的实现.
在您的情况下,您可以使用 Helper 类 -> 类,它不属于层次结构中的任何位置,但具有通用代码以避免重复。
否则,从OO的角度来看-
- FlyingRunningBird 可能不会像 FlyingBird 那样飞。
- 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。 Flying
和 Running
是能力,名称形容词,唯一责任:飞行 resp。 运行.
委派给 birdFlying
和 birdRunning
使“多重继承”显式 并且绝不会降低表达能力。
我有两个 abstract
classes FlyingBird
和 RunningBird
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 中,我复制了 FlyingBird
和 RunningBird
中的所有代码
依赖 class 的聚合是不可能的,因为两个 class 都是抽象的
问题是在 FlyingBird
或 RunningBird
上完成的任何错误修复或修改不会反映在 FlyingRunningBird
中。我也需要更新 FlyingRunningBird
。
有什么方法可以避免 FlyingRunningBird
中的代码重复?或
在FlyingRunningBird
中使用FlyingBird
和RunningBird
来避免代码重复?
我认为有两种方法可以解决这个问题:
- 将方法实现作为
default
方法移动到相应的interface
中,前提是您使用的是 Java 8+,并且这些方法不需要访问字段(其中如果您需要在界面中使用一些访问器或重新考虑您的设计)。 - 组合优于继承,尽管在这种特殊情况下这似乎不太自然。 IE。您的
FlyingRunningBird
可以提供FlyingBird
的实例和RunningBird
的实例(在构建时),它只会将每个接口的方法调用委托给相应的实现.
在您的情况下,您可以使用 Helper 类 -> 类,它不属于层次结构中的任何位置,但具有通用代码以避免重复。
否则,从OO的角度来看-
- FlyingRunningBird 可能不会像 FlyingBird 那样飞。
- 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。 Flying
和 Running
是能力,名称形容词,唯一责任:飞行 resp。 运行.
委派给 birdFlying
和 birdRunning
使“多重继承”显式 并且绝不会降低表达能力。