1

Say I have a Base class called Car and it has 3 derived classes say Ford, Honda and Audi.

The issue is, all three derived classes have exactly same code but minor difference in calling member functions of their respective engines (these engines have separate class).

For example, Ford class calls code which is exactly same as other two classes but do call something like ford_engine-> start(), ford_engine->clean() etc.

//ly  honda  calls   honda_engine->start()   honda_engine->clean();

//ly  Audi calls audi_engine->start()  audi->clean();

Now here the issue is, it has redundant code in all three places with minute difference. How can I have code at one place, most probably in base class and all derived classes use same code?

  • composition over inheritance, make an abstract engine class that the now concrete car object has a reference to – ratchet freak Sep 4 '14 at 22:51
1

The idea is to add a read only protected member variable (i.e. a protected property) engine to your superclass. Then, redefine the accessor in the subclasses to return the proper engine instance. Your code become this->getEngine()->start() and so on.

  • can you please explain by an example? – samprat Sep 5 '14 at 8:50
  • looks like I have solved it.. Thanks a lot for the help – samprat Sep 5 '14 at 10:16
4

First of all, Ford, Honda and Audi probably should not be classes derived from Car. Derivation should reflect differences in behavior on an abstract level.

In this case, it probably makes more sense to simply have a Car object with a field identifying the manufacturer. The Car owns an engine--but in a typical case, you don't need a different class for each brand of engine either; at an abstract level, the brand is generally irrelevant.

As such, you can have something like:

class Car {
    class Engine {
        enum { diesel, piston, rotor, electric, hybrid } type;

        int HP;
        int torque;
        int max_rpm;

        bool running;

        void start() { running = true; }
        void stop() { running = false; }
        // ...
    } engine;

    std::string brand;
    std::string model;
};

In a few cases you honestly need to model an engine at a level of detail where things like firing order really matter, and you'll need much more detail than this. It should still be at a behavioral level though. If you had a Ford_motor vs. Honda_motor the brand should still really be a short-hand for behavioral differences. You really want to maintain the most abstract view you can though, so you usually want to model an engine (car, etc.) in terms of behavior. The difference between a Ford and a Honda motor should be things like one has higher torque and the other higher red-line than the other; these differences can be modeled quite easily by supplying suitable parameters when instantiating the object. If Ford and Honda were to produce engines with identical characteristics (not just power, but power curves, etc.) then the difference in brand is irrelevant to your modeling.

Oh, and no you should not have a getEngine as a member of a Car. A car is a car. It has an engine. If you provide a getEngine at all, it should be a member of AutoPartsStore or something on that order (but unless you're dealing with buying and selling engines, you probably shouldn't have such a thing at all).

When a person starts their car, the don't get the engine and start the engine. They start the car and after they do so (successfully), the car is running. Forcing a client to use a getEngine and start the engine is both crappy from a coding viewpoint and from a modeling viewpoint--starting my car does more than just start the engine. It also controls things like some of the lights, the radio, heating/air conditioning, and so on. One of the basic points of object-oriented programming is to protect client code from dealing with all these internal details, not to force them to deal with the details and use crappy getXxx() syntax to do it!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.