Calling a Class inside a Class

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
bdeonline
Forum Commoner
Posts: 42
Joined: Sun Jul 18, 2004 10:45 am

Calling a Class inside a Class

Post by bdeonline »

Can I do that and is it just like calling a regular class? I know the extends to add a class but I am needing to add 2 classes.
User avatar
markl999
DevNet Resident
Posts: 1972
Joined: Thu Oct 16, 2003 5:49 pm
Location: Manchester (UK)

Post by markl999 »

Yes, you can do that.
You could always try it too? ;)
qads
DevNet Resident
Posts: 1199
Joined: Tue Apr 23, 2002 10:02 am
Location: Brisbane

Post by qads »

Code: Select all

<?php
class a
{
var $b;
function say()
{
echo $this->b->foo();
}
}
//
class b
{
function foo()
{
return "u foo";
}
}
//
$a = &NEW a();
$b = &NEW b();
$a->b = &$b;
$a->say();
?>
thats how i use it, havent really checked with phpdn guys, so i am not sure if its a smart way to do it :P.
McGruff
DevNet Master
Posts: 2893
Joined: Thu Jan 30, 2003 8:26 pm
Location: Glasgow, Scotland

Post by McGruff »

Code: Select all

/*
    Aggregation:
*/
class A
{
    function A(&$aggregated_class)
    {
        $this->aggregated_class =& $aggregated_class;
    }

    function foo()
    {
        // accesses $aggregated_class interface
    }

}
$an_object      =& new WhateverItIs();
$another_object =& new A($an_object);
$another_object->foo();


/*
    Composition (the Factory pattern)
*/
class B 
{
    function B()
    {
        $this->_setFactoryObject();
    }

    function foo()
    {
        // accesses $factory_object interface
    }
    
    //////////////////////////////////////////
    //              PRIVATE                 //
    //////////////////////////////////////////
        
    function _setFactoryObject()
    {
        $this->factory_object =& new WhateverItIs();
    }

}

$object =& new B;
$object->foo();
Aggregation and composition are different ways to associate classes. Notice how, with the second example, WhateverItIs is not exposed in the calling script. In OOP design, you generally want to minimise scope as much as possible in order to isolate discrete responsibilities in their own little module.

That's not to say that aggregation is bad - not at all. WhateverItIs might need to be accessed by several objects in the calling script, or may need to be configured before being associated, so hiding it inside a single class wouldn't be appropriate.

Don't try to associate classes with inheritance. Aggregation is almost always preferred if it's possible. Keep inheritance for cases where one object really is of the same type as the superclass.

Useful links:

http://www.phppatterns.com/index.php/ar ... ew/15/1/1/
http://www.phppatterns.com/index.php/ar ... ew/49/1/1/

phpPatterns has several other articles on design patterns & OOP in php.

There's an (experimental) example of inheritance and aggregation in action here: viewtopic.php?t=25959.

If you are exploring OOP I can't recommend strongly enough that you start unit testing as soon as possible - see the link in my signature.

Instantiation of the factory class in the second example is in its own method to make testing easier.
Last edited by McGruff on Sun Aug 07, 2005 11:16 pm, edited 3 times in total.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

McGruff wrote:

Code: Select all

class A
{
    function A($aggregated_class)
    {
        $this->aggregated_class =& $aggregated_class;
    }

    function foo()
    {
        // accesses $aggregated_class interface
    }

}
$an_object      =& new WhateverItIs();
$another_object =& new A($an_object);
$another_object->foo();
wouldn't A::aggregated_class be a reference to a copy of an object of WhateverItIs? (PHP4) Shouldn't A's constructor take a reference to first argument?
McGruff
DevNet Master
Posts: 2893
Joined: Thu Jan 30, 2003 8:26 pm
Location: Glasgow, Scotland

Post by McGruff »

Well spotted - I've added the reference now.

That's what happens when you don't write the test first.. ;)
Post Reply