Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 有没有更好的方法来创建一个扩展另一个抽象类并添加新特性的抽象类?_Java_Oop_Inheritance_Design Patterns_Abstract Class - Fatal编程技术网

Java 有没有更好的方法来创建一个扩展另一个抽象类并添加新特性的抽象类?

Java 有没有更好的方法来创建一个扩展另一个抽象类并添加新特性的抽象类?,java,oop,inheritance,design-patterns,abstract-class,Java,Oop,Inheritance,Design Patterns,Abstract Class,我有一个抽象类,它有一个具体的方法solve,还有几个由solve使用的抽象方法: public abstract class A{ public void solve(){ //code for solve } public abstract void a(); public abstract void b(); } 然后我有另一个类B,它扩展了A,使用A中的抽象方法重新实现了solve方法,并添加了新方法(c,d)。它还有一个布尔字段,指示

我有一个抽象类,它有一个具体的方法
solve
,还有几个由
solve
使用的抽象方法:

public abstract class A{
    public void solve(){
       //code for solve

    }

    public abstract void a();
    public abstract void b();
}
然后我有另一个类
B
,它扩展了
A
,使用
A
中的抽象方法重新实现了
solve
方法,并添加了新方法(
c,d
)。它还有一个布尔字段,指示它是否必须使用
解算
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的原则。

问题是,OOP的最佳解决方案有时过于复杂。因此,在某些情况下,需要最少工作量的解决方案将是最好的

而且在这个案件中很难做出判断。虽然您尝试创建一个最小、完整且可验证的示例是好的,但它缺少关于应该继承什么的最重要信息:每个类的用途。例如,您可以想象将类
B
拆分为两个可能是有意义的,其中一个覆盖
solve()
,而另一个不覆盖
solve()
,但如果这是一个好主意,则只能决定就每个类的用途提出正确的问题

我怀疑您提出这些问题是因为您想知道在类中重用代码的最佳方法。如果是这样:不要。摘自维基百科文章:

在大多数情况下,仅用于代码重用的类继承已经不受欢迎。主要的问题是实现继承不提供多态可替换性的任何保证重用类的实例不一定可以替换继承类的实例。另一种技术,显式委托,需要更多的编程工作,但避免了可替换性问题。在C++中,私有继承可以用作实现继承的形式而不具有可替代性。公共继承代表“是一种”关系,委托代表“有一种”关系,而私有(和受保护的)继承可以被认为是一种“按”关系实现的继承


有些人已经提到了decorator模式,还有策略模式

但是,可以使用lambdas来注入一些处理程序

处理程序可以使用公共服务/受保护的要求完成:

解决方案复合体通常最好没有继承,但作为字段,委托给字段

在这方面,@LonelyNeuron的答案给出了很好的论据


简言之:当有疑问时,首先将其编码出来,并将其重构为某种优雅的模型。分离关注点等。

我看没有问题。如果您没有发现自己在复制代码,那么您就走上了正确的道路。但这是一个太小的示例,您需要构建类并查看此策略的任何问题。按照此链接学习继承:您的设计对您的特定问题有意义吗?如果是这样,那么它可能至少是有效的。我想说的是,减少类层次结构可能是可取的,因为这可能会导致以后的维护噩梦。您发布的代码不会像您预期的那样工作。您已经在构造函数中调用了solve方法。如果要使其有条件,则需要将
If(useA)
条件放入solve方法中,并从那里进行分支。类似于“条件方法声明”中的“如果USEA是真的,不重写该方法”的情况是不存在的。
class A {
    public final f() {
       ...
       onF(x, y);
    }

    protected abstract void onF(X x, Y y);
}