Ziezi
Ziezi

Reputation: 6467

How to add functionality to derived class?

I have a base class Circle(simply drawing circles) and two derived, from it, classes: Smiley and Frowny, adding two distinctive features, respective "mouth expression" and "eyes". These two classes add the new features, overriding the function draw_lines()1 , whose original is located in Circle.

// class Smiley
class Smiley: public Circle{
public:
   Smiley(Point c, int rr)  : Circle(c,rr), r(rr) { }
   void draw_lines() const;
private:
   int r;
};

void Smiley::draw_lines() const{
    if (color().visibility())
    // add the mouth
        fl_arc(point(0).x + r/2, point(0).y + r/2, r, r, 180, 360);
    // add the eyes
        fl_arc(point(0).x + r/2, point(0).y + r/4, r/2, r/2, 0, 360);
        fl_arc(point(0).x + 3/2 * r, point(0).y + r/4, r/2, r/2, 0, 360);
    // the below is the body of the original function in Circle
    if (color().visibility())
        fl_arc(point(0).x,point(0).y,r+r,r+r,0,360);
}
// class Frowney
class Frowny: public Circle{
public:
    Frowny(Point c, int rr)  : Circle(c,rr), r(rr) { }
    void draw_lines() const;
private:
    int r;
};

void Frowny::draw_lines() const{
    if (color().visibility())
    // add the mouth
        fl_arc(point(0).x + r/2, point(0).y + r, r, r, 0, 180);
    // add the eyes
        fl_line(point(0).x + r/2 - 5, point(0).y + r/2, point(0).x + r,  point(0).y + r/4);
        fl_line(point(0).x + r + 5, point(0).y + r/4, point(0).x + 1.5*r, point(0).y + r/2);
    if (color().visibility())
        fl_arc(point(0).x,point(0).y,r+r,r+r,0,360);
}

Now, two new classes should be derived from class Smiley and Frowny adding specific separate feature for each of them.

// class SmileHat
class SmileHat: public Smiley{
public:
    SmileHat(Point c, int rr) : Smiley(c, rr), r(rr), center(c) { }
    void draw_line() const;
private:
    int r;
    Point center;
};

Similarly for Frowny, with the only difference in the shape of the hat.

Question:

What is the standard practice for adding the new features to each of the classes Smiley and Frawney:

1.Override the already existing(inherited) function, draw_lines() (again) and include the new features ?

void SmileHat::draw_line() const{
    if (color().visibility())
    // add triangle hat
        fl_line(center.x - r, center.y + r/2, center.x , center.y + r);
        fl_line(center.x + r, center.y + r/2, center.x, center.y + r);
    // body of the function override  in Smiley
     if (color().visibility())
    // add the mouth
        fl_arc(point(0).x + r/2, point(0).y + r/2, r, r, 180, 360);
    // add the eyes
        fl_arc(point(0).x + r/2, point(0).y + r/4, r/2, r/2, 0, 360);
        fl_arc(point(0).x + 3/2 * r, point(0).y + r/4, r/2, r/2, 0, 360);
    // the below is the body of the original function in Circle
    if (color().visibility())
        fl_arc(point(0).x,point(0).y,r+r,r+r,0,360);
}

2.Create a new member function to the new classes adding the new feature ?

void add_hat() const{
    // draw hat
}

3.Is there any other more efficient way of doing it ?

Note:

I'm asking the question considering the notion of implementation inheritance, which I don't seem to utilize, by continuously/ repetitively overriding the same function and expanding it, i.e. in each derived class there is an explicit copy of the code from the base class with a small addition.


1. the function draw_line() is a virtual function in class Circle. That is why it is possible to override it the derived classes.

All the additional files for compilation could be found: here. The FLTK could be found here.

Upvotes: 2

Views: 657

Answers (2)

Ziezi
Ziezi

Reputation: 6467

To extend a class and add new features one can:

1.Override the existing(inherited) functions(in the derived class), adding new code that represents the new features. In my case:

void SmileHat::draw_line() const{
    // existing old code
    Smiley::draw_line();
    // newly added feature 
    if (color().visibility())
    // add triangle hat
    fl_line(center.x - r, center.y + r/2, center.x , center.y + r);
    fl_line(center.x + r, center.y + r/2, center.x, center.y + r);
}

2.Define a decorator class containing the basic features to be extended and then derive different classes from it, each adding a specific extension to the basic features. In my case the class hierarchy would look like:

                                     class Circle
                                          |
                                          |
                      - - - -> class CircleDecorator <- - - -  
                     |            |            |             |
                     |            |            |             |    
             class withSmile class withHat1 class withHat2 class withFrown

Upvotes: 1

Marko Krizmanic
Marko Krizmanic

Reputation: 124

draw_lines() method should be declared as virtual:

virtual void Smiley::draw_lines() const {
    //draw smiley implementation here
}

Override draw_lines() and call base method to draw smiley:

virtual void SmileHat::draw_lines() const{
    Smiley::draw_lines(); //call base method to draw smiley
    //do the hat drawing here        
}

Upvotes: 4

Related Questions