我有一个抽象类,它有一个具体的方法solve
和几个solve
使用的抽象方法:
public abstract class A{
public void solve(){
//code for solve
}
public abstract void a();
public abstract void b();
}
然后我有另一个扩展B
的课程A
,使用solve
中的抽象方法重新实现A
方法,并添加新的方法c,d
) 。它还有一个布尔字段,指示是否必须使用solve
A或B
中的{。}}。
public abstract class B extends A{
boolean useA;
public B(boolean useA){
this.useA = useA
}
public void solve(){
if(useA) super.solve();
else // code for solve
}
public abstract void c();
public abstract void d();
}
然后我有一个扩展C
的具体类B
,实现所有方法并有一个布尔值来指示是否必须使用solve。
public class C extends B{
public C(boolean useA){
super(useA);
}
... //code for a,b,c and d
}
有没有办法做得更好?我想也许它不遵循OOP的原则。
答案 0 :(得分:2)
有些人已经提到了装饰模式,也有策略模式。
然而,有人可能会使用lambdas注入一些处理程序。
处理程序可以使用公共服务/受保护的要求完成:
class A {
public final f() {
...
onF(x, y);
}
protected abstract void onF(X x, Y y);
}
解决方案复合体通常比没有继承更好,但作为字段,委托给字段。
因为@LonelyNeuron的答案提供了很好的论据。
简而言之:如果有疑问,请先将其编码,然后将其重构为优雅的模型。分离关注等等。
答案 1 :(得分:1)
问题是,OOP的最佳解决方案有时会过度设计。所以在某些情况下,花费最少的工作的解决方案将是最好的。
在这种情况下,很难判断。虽然您尝试创建一个Minimal,Complete和Verifiable示例很好,但它缺少有关应该继承内容的最重要信息:每个类的目的。例如,您可以想象将类B
拆分为两个可能是有意义的,其中一个执行,另一个不重写solve()
,但如果这是一个好主意,则只能决定问每个班级目的的正确问题。
我怀疑您是在问这些问题,因为您想知道在类中重用代码的最佳方法。如果是这种情况:不要。摘自this维基百科文章:
在大多数方面,仅仅为了代码重用而继承的类继承已经失宠了。主要关注的是实现继承不能保证多态可替代性 - 重用类的实例不一定能代替继承类的实例。另一种技术,显式委派,需要更多的编程工作,但避免了可替代性问题。在C ++中,私有继承可以用作实现继承的一种形式,而不具有可替代性。公共继承代表“is-a”关系,委托代表“has-a”关系,而私有(和受保护)继承可以被认为是“以”关系实现“。