CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 3 123 LastLast
Results 1 to 15 of 38
  1. #1
    Join Date
    Jul 2006
    Posts
    9

    Relationship is-a, has-a and uses-a

    Hi all

    I am bit confusing with is-a, has-a and uses-a relationship
    of class, I know it's a basic concepts of OOPS and Inheritance.

    Is there any other relation ships available ....?

    Could any one please help me in explaining about this in brief
    and simple.

    Thanks and Regards
    Sudhakar.M

  2. #2
    Join Date
    Aug 2005
    Posts
    478

    Re: Relationship is-a, has-a and uses-a

    I have only heard of is-a inheritence and has-a composition relationships. Is a uses-a relationship one where a specific method of a class will use another class for some functionality or something? You could look at UML to show you different ways to model relationships.

    http://en.wikipedia.org/wiki/Unified_Modeling_Language
    http://en.wikipedia.org/wiki/Class_diagram

    http://www.jubatus.com/publications/...ationships.htm
    http://www.objectmentor.com/resource...ssDiagrams.pdf
    Windows XP, Visual Studio 2008, SVN

  3. #3
    Join Date
    Jul 2006
    Posts
    17

    Re: Relationship is-a, has-a and uses-a

    There are only 3 fundamental relationships between classes :-

    1) IS-A
    2) HAS-A
    3) IS-IMPLEMENTED-IN-TERMS-OF
    Imagination is more important than knowledge.
    -Albert Einstein


  4. #4
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: Relationship is-a, has-a and uses-a

    IS-A is quite simply that. A labrador IS-A dog, a printer IS-A peripheral, and so on. IS-A id modelled by public inheritance.

    The difference between HAS-A and IMPLEMENTED-IN-TERMS-OF (or USES) is a bit more subtle, and comes down to whether the contained item is necessary to a user of the owning object.

    For example, a car HAS-A steering wheel. This is a relationship that is implied by the nature of the thing you're modelling, but is not IS-A (a car IS-NOT-A steering wheel). Users of your car class would expect to able to find out things about the steering wheel.

    IMPLEMENTED-IN-TERMS-OF, however, implies an implementation detail, i.e. the contained object could conceivably be of a different type, and the exact type used is of no interest to the rest of the program. So, you might implement a class using a vector to hold several values, but this could also be achieved by using a list. So the choice of contained object is sort of semi-arbitrary - it could be done different ways. (Of course, it may be that there is actually only one way, but that this is still a detail, one that is irrelevant to the user of your class).

    Both HAS-A and IITO are modelled either by containment (preferred) or by non-public inheritance (if the used class has virtual functions that you have to override, for example).
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  5. #5
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: Relationship is-a, has-a and uses-a

    The difference between HAS-A and USES-A is with regard to ownership. In both cases it is likely your class has a pointer to another class although with HAS-A it may have an instance of the class not a pointer.

    With the HAS-A relationship though your class is responsible for the lifetime of the object it contains, so if your class has a pointer to the object it is responsible for deleting the pointer. USES-A may use shared_ptr to the object.

    There are many who will use shared_ptr throughout anyway, but you have to beware of circular references if this happens. For example, if implementing a tree structure, you cannot have a parent having a collection of shared_ptr to its children, and the children having a shared_ptr to their parent. At least one of them must be a weak pointer.

    Ownership issues are not only a coding-level problem. In my opinion they are a design issue too.

  6. #6
    Join Date
    Aug 2015
    Posts
    6

    Re: Relationship is-a, has-a and uses-a

    thanks NM, 15year old comment but STILL the best explanation I've yet to unearth online re the relationships between this subtle difference.

    any code examples anyone can think of and share? A good analogy of when they've used one (and how)? maybe ya went with a has-a relationship and discovered that ya had to change it... and what changes ya made?

  7. #7
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Relationship is-a, has-a and uses-a

    unfortunately NM's post is wrong. it has nothing to do with ownership.

    IS-A
    is about compatible interfaces "A" IS-A "B" is B means that B implements at least ALL of the observable properties of A in a semantically identical and logical way and may add additional properties on top.

    It means that if you are given an 'B' object and you observe it through a filter that only knows about A, it will behave like an A in every observable way.
    The result in C++ is that if true, it means you will typically derive class B from class A

    HAS-A is the simpler one. it's about one class embedding another class (and potentially many more) and making it (partially ) available as an observable property.




    Side note: trying to make real world analogies to real objects makes little sense in trying to explain this, all of those analogies typically tend to break down when trying to apply them to interfaces.
    pretty much everyone will agree that in the real world, a circle is a special case of an ellipse, and a square is a special case of a rectangle.
    The problem starts with... If you really do try to implement a circle a derived class of an ellipse... what happens when you then call static_cast<ellipse*>(&mycircle)->SetSize(10,4);
    do you suddenly get a circle that is 10 wide and 4 high. Wait, my circle is no longer round? what is mycircle.getRadius() now going to return ?
    clearly from observable behaviour and in C++ a circle is NOT an ellipse.
    the square has the same problem and makes it even harder, since a real world square is ALSO a special case of a diamond. how are you going to implement a square that is derived from a diamond and a rectangle ?

    Using the above note. It should also be Obvious that IS-A and HAS-A are exclusive (it can't be both at the same time) but it's also not transitive. Just because A is NOT an B, doesn't imply A has a B (or B has an A).

  8. #8
    Join Date
    Aug 2015
    Posts
    6

    Re: Relationship is-a, has-a and uses-a

    First impressions of codeguru forum: awesome! That's what I call a timely response many thanks.

    I wish (in part, at least) that I hadn't prised open the can of worms a la 'Lynda advanced tutorials ' - the caveats of inner classes and nested classes - before I was down with Java/OOP 101.

    Re 'real world' examples... this is a VERY GOOD POINT! It's a bit like learning to 'see the world' through a different pair of eyes... maybe even code examples (good ones and/or a consensus) are hard to come by.

    Re the analogies, it's a necessary evil, for noobs like me to simply I M A G I N E.... with that in mind,

    is-a - inheritance
    has-a - composition
    uses-a - aggregation

    I hope you see the level I'm at (1!) and would urge clear concise conversation... I didn't really get all you said in the above... code helps

    My bro's a developer, and he's just told me it's quite possible for (an instance of) A to have (an instance of B), where (for example) A is a 'child' (derived class? not sure on nomenclature) of B, for example. That seems to contradict what you mentioned in your closing comments...

    Off to try and make my new access DBConnection work over a LAN! Thanks again

  9. #9
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,825

    Re: Relationship is-a, has-a and uses-a

    it's quite possible for (an instance of) A to have (an instance of B), where (for example) A is a 'child' (derived class? not sure on nomenclature) of B, for example.
    In this example, class d is-a b and also has-a b. class b is a base class and class d is derived from b and also has a member variable which is of type b.

    Code:
    #include <iostream>
    using namespace std;
    
    class b
    {
    public:
    	b(int a = 0) : bp(a) {};
    	void bset(int a) { bp = a;};
    	int bget() { return bp; };
    
    protected:
    	int bp;
    };
    
    class d : public b
    {
    public:
    	d(int a = 0, int b = 0, int c = 0) : b(a), dp(b), bb(c) {};
    	void dset(int a, int b, int c)
    	{
    		bp = a;
    		dp = b;
    		bb.bset(c);
    	}
    
    	void show() {cout << "bp: " << bp << " dp: " << dp << " bb: " << bb.bget() << endl;	}
    
    private:
    	int dp;
    	b bb;
    };
    
    int main()
    {
    	d ddd(4, 5, 6);
    	ddd.show();
    
    	ddd.dset(7, 8, 9);
    	ddd.show();
    }
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  10. #10
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Relationship is-a, has-a and uses-a

    Quote Originally Posted by 2kaud View Post
    In this example, class d is-a b and also has-a b. class b is a base class and class d is derived from b and also has a member variable which is of type b.
    yes, but we're talking different instances of B in this case. the point I was making about "it can't be both" is that if A is-a B, then A can't has-a the same instance of B. I'm sure that with some mangling and pointer manipulations you can technically make it work as such, but it doesn't make a whole lot of sense to do so.

    That's another thing about C++:
    Just because the syntax of C++ and the system it runs on allows you to do someting. Doesn't necessarily make that 'thing' you do a smart thing to do. You can write horribly bad designed code in C++ that will do the job perfectly as expected, but nobody will want to maintain that code.

  11. #11
    Join Date
    Oct 2008
    Posts
    1,456

    Re: Relationship is-a, has-a and uses-a

    Quote Originally Posted by 2kaud View Post
    In this example, class d is-a b and also has-a b. class b is a base class and class d is derived from b and also has a member variable which is of type b.
    not quite, being a private member it's irrilevant from an interface design pov. Even if it were publicly observable, the fact that you have a member of some type T does not imply a valid has-a-T relationship ( that is, it's about design and meaning, not what you can/cannot technically do in a language ).

    for example, consider the following monstruosity

    Code:
    struct A{ operator class B const&() const; };
    struct B: A {};
    A's are substitutable with B's and B's are (somehow) substitutable with A's, should we conclude that A is a B and B is a A ?

    EDIT: BTW, as an example of a somewhat meaningful, simultaneous is-a + has-a relation:

    Code:
    struct IntegerConstant { virtual int Get() const = 0; };
    struct SquaredIntegerConstant: IntegerConstant { virtual IntegerConstant const& GetRoot() const = 0; };
    a squared integer constant is an integer constant ( = you can get a non mutating int from it ) and has an integer constant ( the "parent" integer constant from which the square is computed; note that the very idea behind defining such a class is to expose the root constant, hence extending the "basic" integer constant entity ).
    Last edited by superbonzo; August 5th, 2015 at 03:59 AM. Reason: added example

  12. #12
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,825

    Re: Relationship is-a, has-a and uses-a

    Just because the syntax of C++ and the system it runs on allows you to do someting. Doesn't necessarily make that 'thing' you do a smart thing to do. You can write horribly bad designed code in C++ that will do the job perfectly as expected, but nobody will want to maintain that code.
    Very true.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  13. #13
    Join Date
    Jun 2015
    Posts
    208

    Re: Relationship is-a, has-a and uses-a

    Quote Originally Posted by OReubens View Post
    yes, but we're talking different instances of B in this case. the point I was making about "it can't be both" is that if A is-a B, then A can't has-a the same instance of B. I'm sure that with some mangling and pointer manipulations you can technically make it work as such, but it doesn't make a whole lot of sense to do so.
    It's important to understand that in A is-a B then B is a type (class), whereas in A has-a B then B is an instance (object).

    The archetypical example of both these relationships existing at the same time is delegation. Here A inherits an interface B (is-a) which is then implemented using a B object that A holds (has-a). This is sometimes called dynamic inheritance because the B object can be replaced with other B objects at any time during runtime changing the behavior of A. This is one way to implement the State design pattern.
    Last edited by tiliavirga; August 7th, 2015 at 03:47 AM.

  14. #14
    Join Date
    Jun 2015
    Posts
    208

    Re: Relationship is-a, has-a and uses-a

    I've been asked to comment on my previous post and give an example.

    I cannot say I purposely use delegation to achieve dynamic inheritance very often but delegation tends to sneak into everyday programming anyway. Many design patterns use it and some even depend on it. And if you follow the important OO rules to "program to an interface, not an implementation" and to "favor object composition over class inheritance" then you automatically tend to replace static inheritance with dynamic inheritance without even thinking about it.

    This is traditional basic inheritance whereby a concrete class B is inherited by a class A.

    Code:
    class B { // concrete class
    public:
    	virtual ~B() = default;
    
    	virtual void method() { // may be overridden but stays fixed after compile time
    		std::cout << "Implemented in B" << std::endl;
    	}
    };
    typedef std::shared_ptr<B> B_PTR; // smart B pointer
    
    class A : public B { // inheritance of type and implementation
    private:
    //	void method() override { // override (or don't)
    //	}
    };
    
    void test() {
    	B_PTR b = B_PTR(new A());
    	b->method();
    }

    And this is a functionally equivalent design based on delegation. First the concrete B class (from the above code) is split into an interface and an implementation (B and B_impl respectively). Then A inherits the B interface and holds the B implementation by object composition. Finally A implements the B interface by way of delegated calls to the B object.

    Code:
    class B { // interface
    public:
    	virtual ~B() = default;
    
    	virtual void method() = 0; // abstract
    };
    typedef std::shared_ptr<B> B_PTR; // smart B pointer
    
    class B_impl : public B { // implementation
    private:
    	void method() override {
    		std::cout << "Implemented in B_impl" << std::endl;
    	}
    };
    
    class A : public B { // inheritance of type (A is-a B)
    private:
    	B_PTR b = B_PTR(new B_impl()); // object composition (A has-a B)
    
    	void method() override {  // implementation of the B interface 
    		b->method();      // delegated to a B object that can be replaced at runtime
    	}
    };
    
    void test() {
    	B_PTR b = B_PTR(new A());
    	b->method();
    }

    So in the first code the behavior of the B class is fixed forever after compilation whereas in the second code it can be changed at runtime. This would involve replacing the B delegation object held in A with other differently implemented B objects from inside or outside of A.
    Last edited by tiliavirga; August 10th, 2015 at 01:27 AM.

  15. #15
    Join Date
    Aug 2015
    Posts
    6

    Re: Relationship is-a, has-a and uses-a

    Quote Originally Posted by NMTop40 View Post
    The difference between HAS-A and USES-A is with regard to ownership. In both cases it is likely your class has a pointer to another class although with HAS-A it may have an instance of the class not a pointer.

    With the HAS-A relationship though your class is responsible for the lifetime of the object it contains, so if your class has a pointer to the object it is responsible for deleting the pointer. USES-A may use shared_ptr to the object.

    There are many who will use shared_ptr throughout anyway, but you have to beware of circular references if this happens. For example, if implementing a tree structure, you cannot have a parent having a collection of shared_ptr to its children, and the children having a shared_ptr to their parent. At least one of them must be a weak pointer.

    Ownership issues are not only a coding-level problem. In my opinion they are a design issue too.
    This makes sense to me (for the most part). The code examples are useful to many, but for me right now I struggle to grasp abstract notions.

    Tiliavirga, thanks for sharing so much info (and so clearly . After you cited 'state design pattern' I checked out an article , but I don't think this one is necessarily even a good state design implementation example, let alone an example of dynamic inheritance

    Thanks again to everyone for contributing and sharing. On a somewhat related note,

    Do any/many of y'all UML (class etc) regularly (if at all)?
    If so, Visio still preferred weapon, or any decent web-tools you recommend?!

    Personally, draw.io is the best I've encountered thus far, and even with that I can't seem to easily implement the correct relational connectors between classes. Just wondering, as lately I've been resorting to the old quill and parchment technique.

Page 1 of 3 123 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured