在C ++中,接口类是否继承自具体类是否合理?这是一种不好的味道吗?
我有一个定义行为的接口,以及一个定义实现的继承类。
现在我有另一个类,我想说明"从这个类继承的人需要指定行为 X ,并定义此行为 Y 哪个alread具有有效的默认实现" 。
这种实施是否正确?我对这种抽象/混凝土混合感到困惑。
class IBase
{
public:
virtual ~IBase(){}
virtual void method1() = 0;
}
class ConcreteBase : IBase
{
public:
ConcreteBase(){}
void method1() override { // some impl; }
}
class ISpecialized : ConcreteBase
{
public:
// Here I don't need virtual destructor
void method2() = 0;
}
class ConcreteSpecialized : ISpecialized
{
public:
ConcreteSpecialized(){}
void method2() override { // some impl. }
}
答案 0 :(得分:4)
您应该考虑让它独立存在,而不是ISpecialized
延长IBase
。然后,您可以使用多重继承来使您的具体类派生自两个接口。
class ISpecialized
{
public:
~ISpecialized(){}
void method2() = 0;
}
class ConcreteSpecialized : ConcreteBase, ISpecialized
{
public:
ConcreteSpecialized(){}
void method2() override { // some impl. }
}
答案 1 :(得分:0)
语言允许它,它清晰明了,你可以使用override
注释,这将有助于你重构另一种方法。如果您使用ISpecialized
指定界面,我会考虑重命名I
。
除了不必要的~IBase(){}
之外,你的方法没有任何错误。
如果您想要virtual
析构函数,请使用
virtual ~IBase() = default;
即。 不明确明确定义它。
答案 2 :(得分:-1)
严格来说,从软件设计的角度来看,我不建议这样做。
继承#Not streaming
df.write.format("org.elasticsearch.spark.sql") \
.mode('append') \
.option("es.resource", "log/raw") \
.option("es.nodes", "localhost").save("log/raw")
而不是ISpecialized
类的ConcreteBase
没有额外的好处,因为在这两种情况下,接口都将定义完全相同的方法集。界面是你期望的抽象。
如果两个接口之间没有直接关系,我也建议考虑Mark的答案。在这种情况下,最好将它们分开,从而允许自己继承第一个的具体实现,同时只使用另一个的定义。