问题描述:

Below is current code design (sample). How can I avoid repetition of the code for "methodParent()" (in implementation of both child classes) without losing interface classes?

//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"; }

};

Thanks for the help in advance !

Santosh

网友答案:

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.

Then implement an Abstract class instead of your interface. Basically it's an interface (containing pure virtual methods that will need to be implemented in childrens) but also containing some "non-pure" (already implemented) virtual methods, that can be overriden later if needed.

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

I would do this:

// 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
};

EDIT If you can't change anything go for this:

But... It's ugly :)

//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"; } 
}; 
网友答案:

The question is a bit odd as you would typically use virtual to actually override a method with specific behaviour for a class, but in your case methodParent() is always the same.

You could add private inheritance of implementation (see effective C++, using multiple inheritance judiciously for an example)

class InterfaceParentImpl() //Interface class 
{
public:
  void methodParent() { cout << "PARENT_METHOD";  }
}; 

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

You still need to write it several times, but if you want to change it, you need to do in one place only.

相关阅读:
Top