xistva
xistva

Reputation: 21

PHP Class / OOP : When to "reference" a class within a class vs extend a class?

When is it ideal to:

class USER {
    // stuff about user
}

class PROFILE extends USER {
    // stuff about user's profile
}

and when is it ideal to:

class USER {
    $id;
    $profile;

    function __construct($id) {
        $this->id = $id;
        $this->profile = new PROFILE($id);
        // set profile variables
    }
}

class PROFILE {
    $id;
    // other variables pertaining to profile

    function __construct($id) {
        $this->id = $id;
    }
}

I feel more comfortable with the 2nd example? Are there any specific caveats I should be aware of?

Should I be thinking of one as not mutually exclusive subsets and the other as children?

Upvotes: 2

Views: 163

Answers (4)

Jonathon Reinhart
Jonathon Reinhart

Reputation: 137398

This is the classic question of encapsulation and inheritance.

Use encapsulation:

  • When you want to provide some of the functionality of the base class, but want to hide some of it.
  • When you want to extend / modify the functionality of the base class, but don't need it to be type-compatible.

Use inheritance:

  • When you need derived classes to be type-compatible with the base class. In other words, if the client code will need to refer to instances of Derived with Base references.

In your example, it doesn't make sense for PROFILE to derive from USER. A user has a profile, but a profile is not a user. For this example, it makes sense for the USER class to contain a PROFILE field.

Upvotes: 2

Shoe
Shoe

Reputation: 76240

Usually parent classes are more like generic classes that you are going to extend and rarely use by their own. So inheritance is more like the way it is supposed so be: you extend a generic class.

I'm not gonna go for the animal metaphor again but something like:

class USER {} // generic class

class ADMIN extends USER {} // specific class

class MOD extends USER {} // specific class

has a logic because we extend a generic USER class to specify a class for each type of user.

For anything else that is not hierarchical I'd use encapsulation.

Upvotes: 0

cHao
cHao

Reputation: 86506

Generally, unless you can say that a PROFILE is just a special kind of USER, and in all cases can be treated just like a USER, you don't want to use inheritance to model the relationship. A USER might have a PROFILE, or a PROFILE might be associated with a particular USER, but the two are distinct entities -- so neither one should inherit from the other.

Upvotes: 1

deceze
deceze

Reputation: 522024

I'd say the real way to do it would be:

class User {

    private $id,
            $profile;

    public function __construct($id, Profile $profile) {
        $this->id = $id;
        $this->profile = $profile;
    }

}

class Profile { ... }

new User(42, new Profile(...));

You don't want to extend a class, unless there's a clear hierarchy (Admin extends User).
You should also not couple classes like you did in your User constructor, rather use dependency injection as shown above.

Upvotes: 1

Related Questions