C ++接口类继承自具体类是否合理?

时间:2018-03-05 16:44:02

标签: c++ inheritance

在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. }
}

3 个答案:

答案 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的答案。在这种情况下,最好将它们分开,从而允许自己继承第一个的具体实现,同时只使用另一个的定义。