PHP 类/OOP:何时“引用”类中的类与扩展类?

发布于 2024-12-25 12:24:15 字数 592 浏览 0 评论 0原文

什么时候是理想的:

class USER {
    // stuff about user
}

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

以及什么时候是理想的:

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;
    }
}

我对第二个例子感觉更舒服?有什么我应该注意的具体注意事项吗?

我是否应该将一个视为不互斥的子集,而将另一个视为子集?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

不语却知心 2025-01-01 12:24:16

我想说真正的方法是:

class User {

    private $id,
            $profile;

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

}

class Profile { ... }

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

你不想扩展一个类,除非有一个清晰的层次结构(Admin extends User)。
您也不应该像在 User 构造函数中那样耦合类,而应使用如上所示的依赖注入。

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.

空城仅有旧梦在 2025-01-01 12:24:16

一般来说,除非您可以说 PROFILE 只是一种特殊的 USER,并且在所有情况下都可以像 USER 一样对待,您不想使用继承来建模关系。 USER 可能拥有一个PROFILE,或者PROFILE 可能一个相关联特定的USER,但是两者是不同的实体——因此任何一个都不应该从另一个继承。

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.

硬不硬你别怂 2025-01-01 12:24:16

通常,父类更像是您要扩展的泛型类,并且很少由它们自己使用。所以继承更像是它应该的方式:扩展一个泛型类。

我不会再用动物比喻,但类似这样的东西:

class USER {} // generic class

class ADMIN extends USER {} // specific class

class MOD extends USER {} // specific class

有一个逻辑,因为我们扩展了一个通用的 USER 类来为每种类型的用户指定一个类。

对于任何其他不分层的东西,我会使用封装。

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.

小姐丶请自重 2025-01-01 12:24:15

这是封装继承

使用封装

  • 当您想要提供基类的一些功能,但想要隐藏其中一些功能时。
  • 当您想要扩展/修改基类的功能,但不需要它类型兼容时。

使用继承:

  • 当您需要派生类与基类类型兼容时。换句话说,如果客户端代码需要使用 Base 引用来引用 Derived 的实例。

在您的示例中,从 USER 派生 PROFILE 是没有意义的。用户拥有个人资料,但个人资料不是用户。对于此示例,USER 类包含 PROFILE 字段是有意义的。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文