我有两个'接口'类:AbstractAccess
和AbstractPrint
,以及从它们继承并使用它们的方法的AbstractRun
类。另外,我有两个接口实现:AbstractAccess
的访问器和AbstractPrint
的Print
#include <iostream>
using namespace std;
class AbstractAccess {
public:
virtual string access (void) = 0;
};
class AbstractPrint {
public:
virtual void print (string) = 0;
};
class AbstractRun : virtual public AbstractAccess, virtual public AbstractPrint {
public:
void run (void) {
print(access());
}
};
class Accessor : virtual public AbstractAccess {
public:
string access (void){
return name;
}
void setName(string name) {
this->name = name;
}
private:
string name;
};
class Print: public virtual AbstractPrint {
public:
void print (string s) {
cout << s << endl;
}
};
有没有办法将AbstractRun
中的接口转换为它们的实现或者创建实现类Run只会使用AbstractRun的'run'方法但是实现了接口?
虽然你已经解决了你的问题,但我还是深入研究了这个问题,并且我想解决一些关于继承问题的困惑。
当您的类与另一个类具有“是”关系时,将使用继承。派生类应该是您继承的类的替代。
在你的情况下,你可以安全地说class Print
是class AbstractPrint
和class Access
同样是class AbstractPrint
,因此继承在这里很好。
另一方面,class AbstractRun
不是AbstractPrint
,也不是AbstractAccess
。 AbstractRun
简单地处理/组合了AbstractPrint
and AbstractAccess
。这个关系应该用聚合(或组合)抽象,因为AbstractRun
有一个引用/指向AbstractRun
和AbstractPrint
的指针。这将使AbstractRun
具体化,所以我们将其重命名为Runner
。
class Runner
{
public:
// We now need a constructor to set the references.
Runner(AbstractAccess& access, AbstractPrint& print) :
accessor(access), printer(print) {}
void run (void) {
printer.print(accessor.access());
}
private:
AbstractAccess& accessor; // has a AbstractAccess
AbstractPrint& printer; // has a AbstractPrint
};
现在可以像以前一样定义Access
和Print
。
但是我们也要改进它们:
class Print: public virtual AbstractPrint {
public:
void print (string s) {
cout << s << endl;
}
};
我们不需要虚拟继承。虚拟继承用于解决钻石问题。但是没有钻石比AbstractRunner成为一个具体的类。所以让我们删除不必要的限定符。
class Accessor : public AbstractAccess {
public:
string access (void){
return name;
}
void setName(string name) {
this->name = name;
}
private:
string name;
};
class Print: public AbstractPrint {
public:
void print (string s) {
cout << s << endl;
}
};
此外,如果您有一个兼容C ++ 11的编译器,我建议您为覆盖基本函数的方法添加override
限定符,以便能够对从基类中获取的方法进行去编程。
class Accessor : public AbstractAccess {
public:
string access (void) override { //overrides AbstractAcces method
return name;
}
void setName(string name) { //does not override. is a method at Accessor level
this->name = name;
}
private:
string name;
};
现在,当初始化Runner
时,我们需要传递具体的访问器和打印机。这可以这样做:
// Somewhere in a .cpp - file
Accessor accessor;
Print printer;
Runner runner(accessor, printe);
runner.run(); //will call printer and accessor through the references.