编辑:为了消除一些困惑,我实际上并没有使用 Male
和 Female
。一个更好的例子是父类 Animal
和子类 Cat
和 Dog
。
我对 OOP 有点陌生,但到目前为止我已经很好地掌握了它。然而,有一件事我完全可以找到一种方法来做。
首先,我创建一个基于用户的新对象。用户可以是(对于本例)男性或女性,但如果不检查数据库,我无法检查他们是否是男性或女性。然后,我需要使用其性别的子类创建一个新的用户对象。
例如,这是我当前的(困惑的)代码:
$user = new Person();
$userType = $user->GetUserType($userid);
if ($userType == 'Male') {
$user = new Male($userid);
} else {
$user = new Female($userid);
}
如果我想创建一个新对象,我每次都必须这样做,这是我不想做的事情。
这里还有一些代码可以帮助我们正确理解这一点:
class Person {
function GetUserType($userid) {
$db = mysqlConnect();
$stmt = $db->stmt_init();
// Get the players information
$stmt->prepare("SELECT user_type FROM user_information WHERE user_id = ?");
$stmt->bind_param('i', $userid);
$stmt->execute();
$stmt->bind_result($userType);
$stmt->fetch();
$stmt->close();
$db->close();
return $userType;
}
}
class Male extends Person {
// Male based things here
}
class Female extends Person {
// Female based things here
}
因此,在 Person
类的 __construct
中,我希望它检查用户的性别并设置适当的子类。
最佳答案
So, in the
__construct
of the Person class, I'd like it to check for the users sex and set the appropriate sub-class.
就像在其他地方已经说过的那样, Actor 不会回来,所以你不能这样做。而且参与者无论如何都不应该查询数据库,因为that would be doing work 。如果您不能/不想立即通过 DataMapper 创建正确的子类型或Repository ,您可以使用 State Pattern :
Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.
这是 Behavioral Patterns 之一来自Gang Of Four book 。显然,这里的关键词是行为。状态模式并不是关于不同的子类型(猫、狗)本身,而是关于它们的行为差异。因此我对你的问题发表评论。
示例:
interface GenderBehavior
{
public function someBehavior();
// can add more methods here
}
class FemalePersonBehavior implements GenderBehavior
{
public function someBehavior()
{
// female specific behavior
}
}
class MalePersonBehavior implements GenderBehavior
{
public function someBehavior()
{
// male specific behavior
}
}
class UnknownGenderBehavior implements GenderBehavior
{
public function someBehavior()
{
// either implement a neutral behavior or
throw new LogicException('Unknown Gender set');
}
}
要创建这些实例,您需要添加 Factory
class GenderBehaviorFactory
{
public static function create($sex = null)
{
switch ($sex) {
case 'male':
return new MalePersonBehavior;
case 'female':
return new FemalePersonBehavior;
default:
return UnknownGenderBehavior;
}
}
}
然后,将 GenderBehavior
接口(interface)添加到 Person
类,并将对接口(interface)方法的所有访问传送到Behavior 实例:
class Person implements GenderBehavior
{
private $behavior;
public function __construct()
{
$this->behavior = GenderBehaviorFactory::create();
}
public function changeGender($sex)
{
$this->behavior = GenderBehaviorFactory::create($sex);
}
public function someBehavior()
{
$this->behavior->someBehavior();
}
}
现在,当您第一次创建 Person 时,它将使用 UnknownGenderBehavior
进行实例化,如果您尝试调用 someBehavior
,它将引发异常。当您以男性或女性作为参数调用 changeGender
时,将创建适当的 GenderBehavior
并将其设置为 Person
。然后你可以调用someBehavior
。
关于php - 构造父类时设置对象的子类(动态子类),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10565843/