"Is a" vs "Has a" paradigm

This is a discussion on "Is a" vs "Has a" paradigm within the C++ Programming forums, part of the General Programming Boards category; Originally Posted by zacs7 For example given an aeroplane, it's made up of wheels, wings, etc. But a wing is ...

  1. #16
    Registered User
    Join Date
    Jun 2005
    Posts
    6,261
    Quote Originally Posted by zacs7 View Post
    For example given an aeroplane, it's made up of wheels, wings, etc. But a wing is not an aeroplane and an aeroplane isn't a wing. And aeroplanes often have two wings, so how would you do that with inheritance?
    It depends on how you model it, actually.

    One way of modelling an aeroplace is as an object that has wheels, wings, etc.
    Code:
    class Aeroplane
    {
        // other stuff
    
        Wings wings;
        Wheels wheels;
    };
    The problem with this approach comes if you also wish to implement an Automobile (which also has wheels, but does not have wings). Both the Aeroplane and Automobile classes would need to separately implement behaviours related to having a set of wheels.

    But let's say we can define a couple of classes named HasWings and HasWheels, and those classes have data structures and implement behaviour related to having and operating sets of wings and wheels respectively. We could then do this;
    Code:
    class Aeroplane : public HasWings, public HasWheels
    {
        // other stuff
    };
    and have Automobile only inherit from HasWheels.

    Quote Originally Posted by zacs7 View Post
    Also, by inheriting from other concrete classes your class is becoming stable. That is, it's very hard to change. Your objective should be a balance between stable classes (i.e. pure virtual classes) and unstable classes (clients of pure virtual classes). This would be the reason why laserlight prefers to use MI only from pure interfaces.
    In the example I describe above, the HasWings and HasWheels classes could potentially provide both interface and behaviour - including containment of data. While they would not necessarily be instantiable (i.e. one shouldn't create raw instances of them, so would make their destructor pure virtual) they need not be pure interface classes.
    Last edited by grumpy; 04-14-2010 at 04:45 AM.
    Right 98% of the time, and don't care about the other 3%.

  2. #17
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,596
    Code:
    class Aeroplane : public HasWings, public HasWheels
    {
        // other stuff
    };
    This is incorrect. A plane is not a wing and is not a wheel....ever.

    You can get the same behavior you are talking about by using interface pointers.
    Code:
    class Aeroplane
    {
    ...
         IWing *m_pWings;
         IWheel * m_pWheels;
    ...
    };
    This is most likely how you would want to model such an object especially if the wheel and wing impls were in DLLs. IWheel and IWing define the interface and each impl of it can provide different impls in different DLLs.

  3. #18
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    4,231
    This is incorrect. A plane is not a wing and is not a wheel....ever.
    And where exactly did grumpy claim that a plane was a wing or a wheel?

    As far as I can tell, grumpy only claimed that a plane was a vehicle that `HasWings' and `HasWheels'. I see nothing wrong with this.

    With the inheritance you can get some nice polymorphisms. Each class need do nothing more than expose an `IWing' or `IWheel'.

    Soma

  4. #19
    In the Land of Diddly-Doo g4j31a5's Avatar
    Join Date
    Jul 2006
    Posts
    476
    Quote Originally Posted by phantomotap View Post
    And where exactly did grumpy claim that a plane was a wing or a wheel?

    As far as I can tell, grumpy only claimed that a plane was a vehicle that `HasWings' and `HasWheels'. I see nothing wrong with this.

    With the inheritance you can get some nice polymorphisms. Each class need do nothing more than expose an `IWing' or `IWheel'.

    Soma
    Maybe the analogy of aeroplane is rather off. Let's try this. There's a class "Boss". Now we can make the Boss have multiple roles. You know like one super dude who is so stingy that he doesn't want to hire other people to do the managerial tasks (come to think of it my boss is one of them, that's why we don't have HR for ages. ). So Boss is like GeneralManager, HR_Manager, CEO, all in one package. Now there's another Boss that hires people to do his jobs so the Boss will have GeneralManager, HR_Manager, CEO, etc under his belt.
    ERROR: Brain not found. Please insert a new brain!

    “Do nothing which is of no use.” - Miyamoto Musashi.

  5. #20
    Registered User
    Join Date
    Jun 2005
    Posts
    6,261
    Quote Originally Posted by Bubba View Post
    [code]
    This is incorrect. A plane is not a wing and is not a wheel....ever.
    You misinterpreted my post. I never claimed that a plane is either a wing or a wheel.

    Containment (or has) relationships may be implemented by inheriting from a abstract class that contains and manages relevant objects. That is relevant if behaviour of "contain and manage" of the specifiede objects is needed by multiple concrete classes.

    However, technically a wing may be a plane (as in a planar surface)
    Last edited by grumpy; 04-15-2010 at 04:08 AM.
    Right 98% of the time, and don't care about the other 3%.

  6. #21
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,596
    I see what you are getting at. However, I think aggregation for airplane would be the better approach. Inheriting from objects that 'have a' thing is a bit confusing, especially when aggregation will accomplish the same thing and at the same time be much clearer and avoid the nasty inheritance hierarchy that is not needed here. My recommendation in this instance would be aggregation instead of confusing the issue with inheritance of 'has a' classes.
    Last edited by VirtualAce; 04-15-2010 at 04:57 PM.

  7. #22
    Registered User
    Join Date
    Jun 2005
    Posts
    6,261
    Quote Originally Posted by Bubba View Post
    I see what you are getting at. However, I think aggregation for airplane would be the better approach. Inheriting from objects that 'have a' thing is a bit confusing, especially when aggregation will accomplish the same thing and at the same time be much clearer and avoid the nasty inheritance hierarchy that is not needed here. My recommendation in this instance would be aggregation instead of confusing the issue with inheritance of 'has a' classes.
    That can work when the aggregation involves a defined, or limited number, of objects. It doesn't quite achieve the same thing when the relationship involves having multiple objects, or the program needs to add or remove objects.

    Different types of aeroplanes, for example, can have different numbers (and types) of wheels. A CAD program that helps design an aeroplane, for example would want to support design a generic aircraft, and being able to place wheels on various locations of the aircraft based on engineering design considerations would be useful (or remove a wheel if a user erroneously places on some part of the design).

    There are tradeoffs. I'm not arguing aggregation is never appropriate. Just that the choice between aggregation and inheritence depends on how abstractions are represented and that is determined by the job at hand.
    Right 98% of the time, and don't care about the other 3%.

Page 2 of 2 FirstFirst 12
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. "has a" vs "is a" relationships
    By carebear in forum C++ Programming
    Replies: 9
    Last Post: 05-03-2006, 01:14 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21