假设您有两个函数fun1
和fun2
。有两个类der1
和der2
。 der1
和der2
都实现了fun1
,但只有der2
实现了fun2
。但我需要具有base
指向der1
和der2
的多态行为。将这两个函数同时放在基类(Abstract)中是否有意义,即使只有der2
会同时使用它们?
der1
和der2
相关,我认为der2
应包含der1
。但即使这样,基类也需要声明fun1
和fun2
。我如何实现ISP?下面的代码看起来很好还是有办法以更好的方式重组它?
class base // Abstract
{
public:
virtual void fun1() {//default implementation}
void fun2(){ // used by only der2}
};
class der1 : public base
{
//this also have fun2 as its defined in base.
}
class der2 : public base
{
// should implement fun1 and fun2 both
public:
void fun2() { //implements fun2.}
}
答案 0 :(得分:1)
接口隔离原则仅使用它们所依赖的接口中的所有方法的子集来解决客户端函数或类的问题。例如,想象一下以下情况:
在这种情况下,两个“Client”类都依赖于整个“BigInterface”API,而它们只需要一个方法的子集。在这种情况下,最简单的解决方案是“拆分”大界面并创建有凝聚力的界面,例如: :
在您的具体情况下,具体取决于谁使用der1
,der2
和base
。在没有更多上下文信息的情况下很难知道您的代码看起来不错,但是假设您的客户端类依赖于base
,即使他们只需要fun1
或fun2
,您应该应用与示例中类似的配方,并将您的界面拆分为两个。
希望它有所帮助:)
答案 1 :(得分:1)
不,如果某个派生类没有实现这两个函数,那么将这两个函数放在一个基类中是没有意义的。这将失败Liskov替代原则。
我建议使用接口层次结构:
struct base1
{
virtual void fun1();
};
struct base2 : public base1
{
virtual void fun2();
};
class der1 : public base1
{
public:
virtual void fun1() override;
};
class der2 : public base2
{
public:
virtual void fun1() override;
virtual void fun2() override;
};
base1*
可以指向der1
或der2
,因此只有fun1
。
base2*
同时包含fun1
和fun2
,因此只能指向der2
。