关于c ++:如何在不丢失接口的情况下避免代码重复?

How can I avoid code repetition without losing the interfaces?

下面是当前的代码设计(示例)。如何避免"methodParent()"的代码重复(在两个子类的实现中),而不会丢失接口类?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//Interfaces
//=======================================================

class InterfaceParent() //Interface class
{
   public:
     virtual void methodParent() = 0;
};

class InterfaceChild1() : public InterfaceParent //Interface class
{
    public:
     virtual void methodParent() = 0;
     virtual void methodChild1() = 0;
};
 class InterfaceChild2() : public InterfaceParent //Interface class
{
    public:
    virtual void methodParent() = 0;
    virtual void methodChild2() = 0;
};

// Concrete Classes
//=========================================================

 class Child1() : public InterfaceChild1  // Concrete Class
 {
    public:
     void methodParent() { cout <<"PARENT_METHOD";  }
     void methodChild1() { cout <<"CHILD_1_METHOD"; }
};
class Child2() : public InterfaceChild2 // Concrete Class
{
    public:
      void methodParent() { cout <<"PARENT_METHOD";  }
      void methodChild2() { cout <<"CHILD_2_METHOD"; }
};

感谢您的帮助!

桑托什


这个问题有点奇怪,因为您通常会使用virtual来实际重写具有类的特定行为的方法,但在您的示例中,methodParent()始终是相同的。

可以添加实现的私有继承(参见有效C++,例如,使用多继承性审慎)

1
2
3
4
5
6
7
8
9
10
class InterfaceParentImpl() //Interface class
{
public:
  void methodParent() { cout <<"PARENT_METHOD";  }
};

class Child1 : public InterfaceChild1, private InterfaceParentImpl
{
  void methodParent() { InterfaceParentImpl::methodParent();  }
}

你仍然需要写几次,但是如果你想改变它,你只需要在一个地方做。


If you see"methodParent()", I need to implement it in all the child
classes and is lots of repetition of the code (as well as maintenance
hurdle) for me.

然后实现一个抽象类而不是接口。基本上,它是一个接口(包含需要在儿童中实现的纯虚拟方法),但也包含一些"非纯"(已实现)虚拟方法,如果需要,可以稍后重写。

In general an abstract class is used to define an implementation and
is intended to be inherited from by concrete classes.
More here

我会这样做:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// abstract
class AParent() //Abstract class
{
   public:
    virtual void methodParent() { ... }; // give a first implementation that can be overriden later on, only if needed
    virtual void methodeChild() = 0

};
//Now the concretes
class Child1() : public AParent
{
    public:
     virtual void methodParent() { ... }; // Override (as an example, only if needed)
     virtual void methodChild() { ... }; //implement
};

class InterfaceChild() : public AParent
{
    public:
    //void methodParent() // is inherited from AParent
    virtual void methodChild() { ... }; // implement
};

如果无法更改任何内容,请编辑。为此执行以下操作:

但是…太难看了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//Interfaces
//=======================================================

class InterfaceParent() //Interface class
{
public:
 virtual void methodParent() = 0;    
};
class InterfaceChild1() : public InterfaceParent //Interface class
{
public:
 virtual void methodParent() = 0;
 virtual void methodChild1() = 0;
};
class InterfaceChild2() : public InterfaceParent //Interface class
{
public:
virtual void methodParent() = 0;
virtual void methodChild2() = 0;
};

//Abstract
//=======================================================
//an abstract class to do the transition betwin interfacesChildXX and concrete classes
class AChildXX() : public InterfaceChildXX  // Concrete Class
{
public:
 virtual void methodParent() { cout <<"PARENT_METHOD";  } //It's implemented here for all your childrens, but can still be overriden
 virtual void methodChildXX() = 0;
};

// Concrete Classes
//=========================================================

class Child1() : public AChildXX  // Concrete Class
{
public:
 //void methodParent() { cout <<"PARENT_METHOD";  } //It's inherited
 void methodChild1() { cout <<"CHILD_1_METHOD"; }
};
class Child2() : public AChildXX // Concrete Class
{
public:
  // void methodParent() { cout <<"PARENT_METHOD";  } //It's inherited
  void methodChild2() { cout <<"CHILD_2_METHOD"; }
};