SitePoint Sponsor

User Tag List

Results 1 to 21 of 21
  1. #1
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Discussion on "Inheritance, Aggregation, Composiition, and Polymorphism"

    Following on from a discussion on the PHP forum, I thought it'd be a great idea to start a discussion on this topic for those who are now learning OO in earnest.

    Some terminology I know of and have proberly used myself. I'm not new to OO but I'm not always clued up in the jargon etc.

    So maybe I'll learn something as well Any members who do know OO pretty well, I'd welcome examples of using Inheritance, Aggregation etc

    Thanks

  2. #2
    SitePoint Addict Mower's Avatar
    Join Date
    Feb 2004
    Location
    Aussie Aussie Aussie
    Posts
    307
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ok I'll start.....

    Why use inheritance?

    To bolt onto to other classes...
    To change method / s if your logic is true (without recoding the class)

    Situation

    You have a class written by someone else and you want to chagane few things? you have to decided to either bolt your changes over the top, eg using extends, or recode the class (long way).

    You have a basic class they you use in alot of projects. You can code the class to be generic and use inheritance to add the functionality you need... or you just take that class and recode (long way).

    You have a class that works, but you decided that it should work differntly under this set logic condition. Do you recode? or just

    PHP Code:
    class B{
    }
     
    class 
    extends {
    }
     
    if (!
    $myLogic 'yes')  //if your logic is true for changing the way you want that class to act
    }
    a$ = & new B($var$var,$var);
    }
    else
    {
    a$ = & new C($var$var$var$var);


    any else?? please add

    how to spot inheritance "the extends key word is a give away"

    PHP Code:
     class One extends Two 

    Now to find how to work inheritance I suggest reading Sitepoints The PHP Anthology Volume I chapter 2 OO, and also http://au.php.net/oop


    "Will I ever find my way to GURU?"

  3. #3
    ********* Wizard silver trophy Cam's Avatar
    Join Date
    Aug 2002
    Location
    Burpengary, Australia
    Posts
    4,495
    Mentioned
    0 Post(s)
    Tagged
    1 Thread(s)
    Alright, but what does this do Mower?
    PHP Code:
    class Foo implements Bar 
    PHP5 only

    Okay, that was just to confuse you. A good example for inheritance is to provide "add-on" functionality to an existing object.

    Using Harry's liberal use of SPF articles as an example throughout the PHP Anthology, say you had an Articles object to manage your articles. Display them, loop through them, loop through them by category, all that jazz. Then you write ArticlesAdmin that inherits Articles. Then you write some new functions in that object to allow editing and saving articles.

    Probably described that pretty crappy but you get the idea

  4. #4
    SitePoint Addict Mower's Avatar
    Join Date
    Feb 2004
    Location
    Aussie Aussie Aussie
    Posts
    307
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Alright, but what does this do Mower?

    PHP:

    class Foo implements Bar {
    I started to read about it here http://www.php.net/zend-engine-2.php

    it started to hurt my brain, so I thought I might leave it for a day....

    I will get back to you though


    "Will I ever find my way to GURU?"

  5. #5
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    A good example of Composition is the idea that a class method called

    PHP Code:
    Draw() { ... } 
    Would draw a shape, regardless of what the shape is, ie A circle, rectangle, square etc. This from the theory I can understand, and why it'd actually work.

    Would an example be better though ? Used Composition myself without realising it An alternative to Composition is Aggregation but I'm not so familiar with this

  6. #6
    SitePoint Evangelist
    Join Date
    Jul 2001
    Location
    Michigan, USA
    Posts
    414
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Check out http://www.sitepoint.com/forums/show...8&postcount=14 It's an old post by Vincent, who used to be a big poster around here, and describes and gives solid examples of some key object oriented concepts. The entire thread (http://www.sitepoint.com/forums/showthread.php?t=59898) is probalby one of my favorite SitePoint Posts of all time.

  7. #7
    SitePoint Addict
    Join Date
    Mar 2003
    Location
    Germany
    Posts
    216
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Also there is a very nice article on javaworld.com that discusses implementation inheritance versus implementing interfaces, which will be a subject in PHP5 programming as well. It also makes use of composition.
    You can find it here:

    http://www.javaworld.com/javaworld/j...1-toolbox.html

    Even though it's Java based, I found it very readable and insightful.

    Most good designers avoid implementation inheritance (the extends relationship) like the plague. As much as 80 percent of your code should be written entirely in terms of interfaces, not concrete base classes. The Gang of Four Design Patterns book, in fact, is largely about how to replace implementation inheritance with interface inheritance. This article describes why designers have such odd beliefs.
    And once again I can highly recommend "Design Patterns Explained" by Allan Shalloway, which is a very readable introduction to OO and design patterns.

    The most basic of UML diagrams is the Class Diagram. It both describes classes and shows the relationships between them. The types of relationships that are possible are

    • When one class is a "kind of" another class: the is-a relationship
    • When there are associations between two classes

      - One class "contains" another class: the has-a relationship

      - One class "uses" another class
    There are variations on these themes. For example, to say something contains something else can mean that

    • The contained item is a part of the containing item (like an engine in a car).
    • I have a collection of things that can exist on their own (like airplanes at an airport).
    The first example is called composition while the second is called aggregation.

  8. #8
    SitePoint Wizard gold trophysilver trophy
    Join Date
    Nov 2000
    Location
    Switzerland
    Posts
    2,479
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If you'll excuse the links to self;

    Inheritance
    Aggregation and Composition.

  9. #9
    SitePoint Addict
    Join Date
    Mar 2003
    Location
    Germany
    Posts
    216
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by HarryF
    If you'll excuse the links to self;
    Of course we do... As usual you have put it in very clear and understandable terms. Cheers.

    While reading those pages, something occured to me: If you aggregate another object in a class by passing it as a parameter (by reference), isn't this a bit like those "evil" global variables? As you said yourself there, another class that also uses the object can alter the object's state, and the first "holder" class has no control over this.

    I haven't thought about this before. Could this cause problems, or is it rather just a theoretical issue?

  10. #10
    SitePoint Wizard gold trophysilver trophy
    Join Date
    Nov 2000
    Location
    Switzerland
    Posts
    2,479
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    While reading those pages, something occured to me: If you aggregate another object in a class by passing it as a parameter (by reference), isn't this a bit like those "evil" global variables? As you said yourself there, another class that also uses the object can alter the object's state, and the first "holder" class has no control over this.

    I haven't thought about this before. Could this cause problems, or is it rather just a theoretical issue?
    Think there's no clear answer there but yes it's an issue. There will be cases where you need to allow anyone to alter the reference and cases where you don't. If some object closes a database connection object, for example, upstream of another object that still has queries to perform, its a problem.

    One approach to solving this is to have some form of "manager" class as Jeff did with WACT (the DBC classes) which provides methods for fetching instance of the "shared object" while managing it's state invisibly.

  11. #11
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)


    Not yet scripting to the point that this has become a problem for me though, does anyone have any examples where there would be a problem though ?

    Thanks

  12. #12
    SitePoint Zealot
    Join Date
    Mar 2004
    Location
    Netherlands
    Posts
    138
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    While reading those pages, something occured to me: If you aggregate another object in a class by passing it as a parameter (by reference), isn't this a bit like those "evil" global variables? As you said yourself there, another class that also uses the object can alter the object's state, and the first "holder" class has no control over this.
    This is an issue of trust. An object is like a person which does everything you say to him (if he is capable to do it). It's methods define his capabilities.

    If I don't trust someone to be careful with the capablities I provide him, I should provide him only the capabilities I trust him to use carefully.

    Instead of a Database object, you might send him a DatabaseAccess object containing a Database object. Only the DatabaseAccess object has access to the Database object it contains (private variable).

  13. #13
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by DJ P@CkMaN
    A good example for inheritance is to provide "add-on" functionality to an existing object.
    Actually that can be an ever so slightly dubious use of inheritance. You can often get away with this, and save yourself some code in the process, but it is also a source of object spaghetti. The reasons it doesn't always work so well are pretty subtle though. Really you want the "is a" relationship to refer to abstract characteristics (and you meant "class" not "object" right? ).

    Say you have a house. Your friend has a guest house. I suspect that there are people reading this that have already mentally written...
    PHP Code:
    class GuestHouse extends House { ... } 
    Most of the time you won't be bitten, but say someone has written this...
    PHP Code:
    function payPropertyTax(&$house) {
        
    $payable $house->getTotalOccupants() * $rate;
        ...

    Guest house will have to extend getTotalOccupants() to mean the owners of the house (who may not even be resident) which is slightly unnatural. We would like to not have this ambigious method at all, but having chosen the extension path we have to take everything from House whether we like it or not and adapt it.

    We are breaking the "is a" relationship here with these concrete classes whenever something in House does not precisely match the same concept in GuestHouse. Really they are concrete variations of some higher concept...
    PHP Code:
    class House { ... } // @abstract
    class PersonalHouse extends House { ... }
    class 
    GuestHouse extends House { ... } 
    Fortunately this is an easy refactoring to carry out. The taxation code would still have to be tidied, but at least everything now has a place. The getOccupants() method only applies to PersonalHouse. The superclass will never be instantiated, and so is unlikely to go a separate way from it's concrete subtypes. Splitting hairs? Possibly, but our two subtypes can now vary independently and that means we have squeased out a little more decoupling.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  14. #14
    SitePoint Addict
    Join Date
    Mar 2003
    Location
    Germany
    Posts
    216
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by HarryF
    There will be cases where you need to allow anyone to alter the reference and cases where you don't.
    When I read Java articles that touch on the issue of wrappers and aggregation and the like, somehow this issue is never mentioned. It looks like they implicitly expect that the wrapped/aggregated object is not touched from the outside anymore. Guess you just have to hope for the best? Unless you implement this manager you spoke of (a bit like a singleton then?). Passing "safe" objects (like a DAO instead of a db connection) also sound reasonable. Thanks for your answers, Harry and meryn.

  15. #15
    SitePoint Addict
    Join Date
    Mar 2003
    Location
    Germany
    Posts
    216
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lastcraft
    PHP Code:
    class House { ... } // @abstract
    class PersonalHouse extends House { ... }
    class 
    GuestHouse extends House { ... } 
    Actually this touches upon a subject I read about today (here), namely the Decorator pattern. Maybe you could solve this problem also by implementing Guesthouse as a wrapper (decorator) for house?

    PHP Code:
    class GuestHouse {
    function 
    Guesthouse(& $house) {
        
    $this->house= & $house;
        ...
    }
     
    function 
    GetRooms() {
        return 
    $this->house->getRooms()
    }

    The two types of houses would not be interchangeable, because you wouldn't necessarily implement all methods of the aggregated object (e.g. in this case you wouldn't implement the payPropertyTax() method). The advantage would be that the two classes would be loosely coupled (you avoid the fixed inheritance hierarchy). But that's just a quick idea off the top of my head, not sure if this would work out here. Just wanted to point out that there will usually be several paths to a solution, and everywhere I read that you should avoid inheritance when possible.

    P.S. Just occured to me that in

    PHP Code:
    function payPropertyTax(&$house) { 
        
    $payable $house->getTotalOccupants() * $rate
        ... 

    you should then enforce a class type for the argument? Like

    payPropertyTax (House $house)

    so that the client code programmer would know that he is not supposed to pass a GuestHouse in there? But we have to wait a bit for that, of course. (Or you could say "ouch, this looks just like Java now..." )

  16. #16
    SitePoint Addict Mower's Avatar
    Join Date
    Feb 2004
    Location
    Aussie Aussie Aussie
    Posts
    307
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I have just made the switch to OO and loving it.... it has taken a weeks to learn the basics properly, but finaly I have it down pat.

    anyway thank you to these people for there help

    Widow Maker, DJ P@CkMaN, and duuuudie

    oh and thanks to Harry Fuecks for a cool book


    PS.

    DJ P@CKMaN I will get back to about interfaces... they still hurt my head LOL


    "Will I ever find my way to GURU?"

  17. #17
    gimme the uuuuuuuuuuu duuudie's Avatar
    Join Date
    Feb 2004
    Location
    Switzerland
    Posts
    2,253
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Mower
    DJ P@CKMaN I will get back to about interfaces... they still hurt my head LOL
    lol, you have no idea what he did to me so that I understand references

  18. #18
    SitePoint Evangelist
    Join Date
    May 2004
    Location
    New Jersey, USA
    Posts
    567
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by mkrz
    When I read Java articles that touch on the issue of wrappers and aggregation and the like, somehow this issue is never mentioned. It looks like they implicitly expect that the wrapped/aggregated object is not touched from the outside anymore. Guess you just have to hope for the best?
    You're missing an entry from your list:

    - Utilization is an association that simply documents an interaction between two objects. (Frequently this is simply referred to as 'an association'.)

    - Aggregation is an association that specifies a whole<->part relationship.

    - Composition is a form of aggregation that requires: (1) a part instance be included in at most one composite at a time; and (2) the composite object is responsible for the lifespan of the part.

    Think of them this way:

    BigThing <----> SmallThing

    Relationship.....Creating Big.....Destroying Big
    ----------------------------------------------------
    Utilization........nothing............nothing
    Aggregation.....Small Exists.....nothing
    Composition.....CreatesSmall....DestroysSmall

    The utilization can start after the creation of both, and can end at or before the destruction of either.

    The aggregation requires the smaller to exist when the larger is created, but the smaller could certainly persist after the larger is destroyed.

    The composition, as mentioned before, creates the smaller with the larger, and destroys the smaller with the larger.

    So if you're using a common database connection, you're just using it. Since you're using it, you put it back the way you found it when you're finished. (Everything I need to know about OOP I learned in Kindergarten... ;-)

    If your Decorator aggregates a single Decoratee object, that object should be passed to the Decorator c'tor.

    And if your Application is composed of a Model, View, and Controller object, then the Application will create them when it is started, and destroy them on shutdown.

    Does this help?

    =Austin

  19. #19
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes, it does But my mind doesn't think in those terms though

    Might be thick, but I/we need more examples

  20. #20
    SitePoint Member
    Join Date
    Sep 2004
    Location
    herts, UK
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    keeping it simple

    An easy test to use when deciding to inherit or aggregate is the "is a" or "has a" test. As briefly mentioned in the post on this thread by lastcraft.

    For example say I have 3 classes. Person, User, and Address. Person is the main base class that includes an ID, hair colour, first name, etc. This class will then be used to create the User class, but should User inherit or aggregate the Person class? The simple test is; if User "is a" Person then use inheritance, if user "has a" person use aggregation. Well the latter obviously doesn't sound right, so inheritance it is.

    Address would want to be placed in person, so if another class such as Client is created and inherits from the Person class, it also has access to the Address methods and properties. But should it be inherited or aggregated? Well the relationship is, Person has an Address. So aggregation it is.

    Why aggregate at all? Could the address details not be embedded into the person class? Well the answer is code re-use and modulation. For example a new class could be created called Organisation. Organisations also have addresses, so the Address class could be aggregated into this new class.

    Hope this helps you decide whether to inherit or aggregate. Thanks for everyone who previously posted useful information on this great post.

    BuR

  21. #21
    SitePoint Zealot
    Join Date
    Feb 2003
    Posts
    156
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Dug up an old topic there.

    I think the is-a vs. has-a language test is very limited. When you have objects that do not map to real-life objects (which is quite often), you won't be able to answer that question. The other issue is that "is-a" is heavily overloaded, most people that have stumbled across substitutability or the Circle-Ellipse-Issue probably know what I am talking about. Otherwise read:
    http://www.parashift.com/c++-faq-lit...heritance.html
    or if you are really brave and don't mind wasting half a day: http://c2.com/cgi/wiki?LiskovSubstitutionPrinciple

    (Granted, the first link certainly doesn't stricly apply to PHP wrt to the language restrictions, but it illustrates a general aspect of OO)

    The problem (IMHO) with resorting to reasoning about the real world and applying it to your design verbatim, is that you're not making a 1-1 copy of the real world. Design and Programming means abstraction with respect to certain goals. And depending on what your goals are, you will (or should) reason differently. This is well illustrated in the Circle-Ellipse-"Paradox". To respond to your example: A user may indeed "have" different persons in certain circumstances (like shared accounts) or you could be building a MMRPG and suddenly with a "person" you could have different "semantics" even though the class you derive from it has the same attributes and methods. I've loooked into a few recent Java-Books, and some are even so strict as to say: If you are subclassing, make sure that you can always substitute an instance of the subclass for an instance of the superclass, which IMHO is a very guidance in statically typed languages. But with languages like PHP I haven't yet decided wether that's also the case, I guess it's safe to say that the more library-like your is supposed to be, the more you should adhere to it.

    I'd say with the way things have evolved over the past few years: "when in doubt composite". If you are protoyping or know the system is not going to be maintained/extended (yeah, right...), then you could do inheritance for code reuse, but while that was once an apparent cornerstone of OO ("code re-use through inheritance"; "if it doesn't have inheritance, it's not OO"), there are few people today that would support this view unrestrictedly.


Bookmarks

Posting Permissions

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