0

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

Santosh
  • 147
  • 7
  • Questions that are primarily opinion-based are generally not allowed on Stack Overflow (`Can anybody suggest..`). Furthermore, your question is too broad, and you may need to ask separate question threads for each of your questions. – AStopher Jun 26 '14 at 08:31
  • 3
    You've put "now my question is:" but it's not followed by a question, just a number of statements, some of which make no sense ("The interface classes are must"). –  Jun 26 '14 at 08:34
  • Create `class ParentImpl : public InterfaceParent` which implements `methodParent` and derive childs from that class. You can create more than one with different implementations. – piotrekg2 Jun 26 '14 at 08:37
  • Thanks for your replies. I am new to this forum and I am sorry to ask opinion based question. But at the moment my only question is "I want to know how can I avoid code repetition without loosing the interfaces?" – Santosh Jun 26 '14 at 08:40
  • @Santosh Then you added too much information to the question. – AStopher Jun 26 '14 at 08:42
  • Derive them from one common base class. – Spook Jun 26 '14 at 08:46
  • I just edited the question for better understanding. I will take care of this in my next communications. But thanks for the suggestions. – Santosh Jun 26 '14 at 08:46
  • 1
    @Santosh It's still incorrect. They are not your questions; your question is `I want to know how can I avoid code repetition without loosing the interfaces?`. Also, in future, please do not ignore suggested edits of higher-rep users (such as myself), since there are still errors in your question. – AStopher Jun 26 '14 at 08:49
  • @Santosh Stop declining suggested edits, which improve the question. The question's rating shows that it is a adverse question, and I am attempting to improve it. – AStopher Jun 26 '14 at 08:54
  • I stopped. Sorry to trouble you again. – Santosh Jun 26 '14 at 08:58
  • @Santosh You need to remove the `Now my question is:` and replace it with something such as `Points to consider:`, since moderators keep declining my edit. Changing it will significantly change this question around for the better. – AStopher Jun 26 '14 at 09:06
  • 1
    @ zyboxinternational I have edited my question. I hope it is better now. Thanks for all your help. – Santosh Jun 26 '14 at 09:17

2 Answers2

1

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"; } 
}; 
Community
  • 1
  • 1
  • Thanks for your answer. But I cannot loose my interface classes. I have re-phrased my question accordingly. – Santosh Jun 26 '14 at 09:48
  • 1
    I dont see any changes, can you explain me why you can't loose your interfaces? –  Jun 26 '14 at 09:49
  • I cannot loose interfaces because the project in past is designed to be handle two different library implementations with common interfaces exposed to the GUI code and final users. Also, all the interfaces are compiled as a separate dll and cannot be linked with both the libraries. I hope, I am clear in my description. Thanks ! – Santosh Jun 26 '14 at 11:16
  • I think this is a nasty design flaw but w/e. Just be very sure that you can't change this portion of code, don't be lazy :) –  Jun 26 '14 at 11:36
  • Thanks for your time. I just wanted to make myself clear with "class AChildXX() : public InterfaceChildXX" line. Here, InterfaceChildXX means all the interface child classes (i.e. InterfaceChild*), right? BTW: I talked to my coordinator and I am not allowed to modify interfaces. Your solution is not that ugly ! Because at least on one occasion with 12 children and 20 common methods, I had much uglier way by using macros. – Santosh Jun 26 '14 at 12:51
  • Haha no doubt that could be ulgier, and yes by InterfaceChildXX I mean InterfaceChild*. –  Jun 26 '14 at 12:55
  • Thanks a lot for your valuable time ! I am going to use your solution in my project. – Santosh Jun 26 '14 at 12:57
  • It's not pretty but get the job done, following your specifications. –  Jun 26 '14 at 13:01
1

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.

  • Then I think it's more appropriate to use an *Abstract* instead of an *Interface*. This way you avoid not only redefinition but also have your code maintenable because located in one place. Plus you can redefine your `methodParent()` if needed into the child classes. –  Jun 26 '14 at 09:16
  • Thanks for your answer. But I cannot loose my interface classes. I have re-phrased my question accordingly. – Santosh Jun 26 '14 at 09:49