我写了一个定义许多受保护方法的基类。这些方法在其子类中调用。 这些方法定义了其子类的基本操作。 例如:
class Base{
protected void foo(){}
protected void bar(){}
}
class Sub1 extends Base{//The sub class only needs Base.foo()
public void po(){
...
foo();
...
}
}
class Sub2 extends Base{//The sub class only needs Base.bar()
public void ko(){
...
bar();
...
}
}
class Sub3 extends Base{//The sub class needs both Base.bar() and Base.foo()
public void lo(){
...
bar();
...
foo();
}
}
我只是想知道它是否是一个好的OOP设计?阅读消息来源,我们知道Sub1
根本不需要Base.bar()
,Sub2
根本不需要Base.foo()
。我认为这有点多余。但我不知道更好的解决方案,任何人都可以给出一些建议吗?谢谢!
答案 0 :(得分:3)
通常,您应该在设计中避免使用这些对象依赖项。如果foo()和bar()的功能在派生类中没有变化,您可能希望将它放在外部类中并改为使用它:
class Base{
}
class Helper1 {
public void foo(){}
}
class Helper2 {
public void bar(){}
}
class Sub1 extends Base{
private Helper1 a = new Helper1();
private Helper2 b = new Helper2();
public void po(){
...
a.foo();
...
b.bar();
}
}
class Sub2 extends Base{
private Helper2 b = new Helper2();
public void ko(){
...
b.bar();
...
}
}
这个foo&吧示例看起来不太好。您的问题可能是对对象的责任分配不当或继承的滥用。发布真实代码有助于写出更好的答案。
答案 1 :(得分:2)
问题应该是“sub2 a Base”,例如青蛙是动物吗?是的,青蛙可以继承动物,但青蛙不应该继承哺乳动物。
如果sub2 是基础,那么你就是在正确的轨道上,如果base只是一个可能有用的函数集合,那么就会出现问题。
答案 2 :(得分:1)
我的想法
1-如果您是第一次进行设计,请尝试遵循Dependecy注入原则,因为我可以清楚地看到您在不同的子类中创建Helper1,Helper2对象,并且可能也在复制代码。
2-如果您不需要helper1和helper 2的不同实例,或者将它们设置为Virtual,那么我建议将Helper1和Helper 2作为基类中的属性,以便在需要时可以覆盖它们。
3-您直接编写实现,您的客户端代码直接依赖于具体类使用Interfaces,它将使您的类更易于测试。
4-这里是金色的规则:如果你所处理的问题并不那么复杂,而且你不会在不久的将来看到改变它们的理由而不是使用你正在做的事情,那么就不要让你这么做生活复杂。所有优秀的oop progrmming都很好但是如果你看到一个更好更简单的解决方案而不是实现更简单的becoz使用ABSTRACTION你需要付出复杂的代价。
一个更重要的规则:看看您是否在不改变设计的情况下对您的课程设计进行了测试,而不是设计正确。
答案 3 :(得分:1)
我发现这是一个Interface segregation Principle问题的SOLID规则之一。
如果您的子类不需要所有基类函数,您可以将基类拆分为更具体的基类或接口