Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 将子类指定给父类中的变量_Php_Oop_Inheritance - Fatal编程技术网

Php 将子类指定给父类中的变量

Php 将子类指定给父类中的变量,php,oop,inheritance,Php,Oop,Inheritance,我有以下相关课程: class cars { public $cars; public function addCar($name, $car) { $this->cars[$name] = $car; } public function getCars() { return $this->cars; } public function getCar($name) {

我有以下相关课程:

class cars {

    public $cars;

    public function addCar($name, $car)
    {
        $this->cars[$name] = $car;
    }

    public function getCars()
    {
        return $this->cars;
    }

    public function getCar($name)
    {
        return $this->cars[$name];
    }

    public function getParams()
    {
        return $this->params;
    }
}

$cars = new cars();

class bmw extends cars {

    private static $_instance = null;
    protected $params;

    function __construct()
    {
        $this->params['param'] = 'foo';
    }

    public static function init()
    {
        if (self::$_instance === null) {
            self::$_instance = new self;
        }

        return self::$_instance;
    }
}

$cars->addCar( 'bmw', bmw::init() );
基本上,我需要从父类访问所有子类。并在已定义的子类上使用父类中定义的方法。添加新的子类时不应修改父类

最后,它应该是这样工作的:

foreach( $cars->getCars() as $car )
{
    foreach( $car->getParams() as $key => $param )
        echo "$key = $param";
}

正确的方法是什么?

很难提供帮助,因为不太清楚您想要实现什么

在我看来,您需要Registry类(carDealer),一个具有公共(针对每个子级)方法的抽象类,以及该类的子级(Bmw)

比如说:

// You seems to need what is called sometimes a Registry. 
// Something which deal with keeping and delivering a group of 'related' classes, as a register.
class CarsDealer
{
    public $cars;

    public function addCar($name, $car)
    {
        $this->cars[$name] = $car;
    }

    public function getCars()
    {
        return $this->cars;
    }

    public function getCar($name)
    {
        return $this->cars[$name];
    }
}

// then you need a basic contract for each concrete classes 
// that will have the same nature and so will extend it 
abstract class Car
{
    protected $params;

    public function getParams()
    {
        return $this->params;
    }
}

// finally the concrete class
class Bmw extends Car
{
    public function __construct($params = null)
    {
        $this->params['param'] = $params;
    }
}

$carsDealer = new CarsDealer();

$carsDealer->addCar('bmw', new Bmw('foo'));

foreach ($carsDealer->getCars() as $car)
{
    foreach ($car->getParams() as $key => $param) {
        echo "$key = $param";
    }
}
请注意一些基本规则/良好做法/惯例:

  • 类命名,始终大写
  • 职责(Bmw类不应具有getCars方法,至少在本例中不应如此)
  • 方法、参数的选择

如果您只需要获取此“参数”,请使用另一种方法:-)


基本上我需要从父类访问所有子类
所以你想重新设计OOP?这是一件非常出乎意料的事情:-)发生了一些非常奇怪的事情。“Cars”是一个数组,而扩展它的“bmw”是一个单独的实例(某种类型)。现在还不清楚您想在这里做什么。我想在一个var中获取cars类的所有子实例,然后在这些实例上使用cars类中定义的方法。您不能在另一个容器/注册表中收集有问题的实例吗?为什么它必须是自动的…在课堂上?至少摆脱未使用的实例会更加困难,当你有一个automagic运行对象表时,gc本身不能再帮助你了。我可能应该使用Registry来实现这一点。谢谢你的帮助。
class cars {

    public $cars;

    public function addCar($name, $car)
    {
        $this->cars[$name] = $car;
    }

    public function getCars()
    {
        return $this->cars;
    }

    public function getCar($name)
    {
        return $this->cars[$name];
    }

    public function getParams($obj)
    {
        return $obj->params;
    }


}

$cars = new cars();

class bmw extends cars {

    private static $_instance = null;
    protected $params;

    function __construct()
    {
        $this->params['param'] = 'foo';
    }

    public static function init()
    {
        if (self::$_instance === null) {
            self::$_instance = new self;
        }

        return self::$_instance;
    }
}

$cars->addCar( 'bmw', bmw::init() );

print_r( $cars->getParams($cars->getCar('bmw')));