【问题标题】:php oo programming parent to instantiate child [duplicate]php oo编程父实例化子[重复]
【发布时间】:2012-12-12 19:37:57
【问题描述】:

可能重复:
What exactly is late-static binding in PHP?

我想构建一个抽象类,它将使用静态函数实例化它的子类。

<?php

class A
{
    protected $value;

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

    public static function create($value)
    {
        /* A must not know about B! 
         * I give that example for the context understanding */
        return **new B**($value);
    }
}

class B extends A
{
}

当然A没有知道B..我不知道这是否可能,我不想在我所有的170个子类中实现create函数...

你认为我应该使用 Factory 来返回我的 170 个类之一的实例吗?这很麻烦,也不是很容易维护..

【问题讨论】:

  • 抱歉,我不明白你到底想要什么。
  • 有可能,见static关键字或后期静态绑定。很可能你做错了(因为你可以只使用标准构造函数),只是这样说,这样你以后就可以不说你没有被警告过。
  • 正如你提到的,A 不会知道它的任何孩子,也不应该知道。您正在努力实现的预期行为是什么?听起来您确实在寻找工厂设计。
  • 170 个子类 - 这是另一种出现问题的气味。只是说,可能有合理的理由,但通常这是你做错事的明显迹象。
  • new static() 会工作...但是去工厂,它好多了。

标签: php oop


【解决方案1】:

我找到了解决办法,但是可以吗?

<?php

class A
{
    protected $value;

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

    public static function create($value)
    {
        $child = get_called_class();
        return new $child($value);
    }
}

我测试了它,它工作正常,它在我的上下文中真的很有用。我不知道它是否丑陋,因为父类不知道关于子类,如果子类类不存在,调用者将不允许调用创建函数..

现在,对于我的实际测试,我使用:

$graph->setBgcolor(Bgcolor::create('yellow')->valid());

 public function setBgcolor(Bgcolor $bgcolor)

【讨论】:

    【解决方案2】:

    一个成功的实现可能是这样的

    class A
    {
        protected $value;
    public static function create($value)
    {
        $type = "NotDivisible";
        for ($i = 2; $i <= 10; $i++) {
             if($value % $i == 0)
             {
                 $type = "DivisibleBy".$i;
                 break;
             }
        }
        $instance = new $type;
        $instance->value = $value;
        return $instance;
    }
    }
    
    public class DivisibleBy2 extends A
    {
    } 
    
    public class DivisibleBy3 extends A
    {
    } 
    
    public class DivisibleBy5 extends A
    {
    } 
    ...
    

    等等....(我还没编译,语法错误见谅)

    现在您知道静态方法与创建的对象实例无关,因为这就是我们首先创建静态方法的原因。

    因此您可以将它们放在任何其他类中,恭喜您已经实现了工厂设计模式。

    但这不是一个好的实现。

    【讨论】:

    • 对不起,这不是我在等待的,家长也不应该知道子类的类型......但无论如何感谢您的时间:)
    【解决方案3】:

    另一种解决方案是使用静态函数并使用基本的新...

    <?php
    
    class A
    {
        protected $value;
    
        public function __construct($value)
        {
            $this->value = $value;
        }
    }
    

    现在,对于我的实际测试,我使用:

    $graph->setBgcolor(new Bgcolor('yellow'));
    

     public function setBgcolor(Bgcolor $bgcolor)
    

    我还是觉得

    Bgcolor::create('yellow')->foo()
    

    看起来比

    (new Bgcolor('yellow'))->foo()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-31
      • 2023-03-05
      相关资源
      最近更新 更多