构造函数可以访问PHP中的父私有属性吗?
在PHP中处理继承时,我发现自己缺乏一些知识,主要是关于构造函数和私有属性 让我们以这段代码为例:构造函数可以访问PHP中的父私有属性吗?,php,oop,inheritance,type-hinting,Php,Oop,Inheritance,Type Hinting,在PHP中处理继承时,我发现自己缺乏一些知识,主要是关于构造函数和私有属性 让我们以这段代码为例: <?php class Module { public $type; public function __construct($type) { $this->type = $type; } } class BModule extends Module { } class CModule extends BModule { } cl
<?php
class Module
{
public $type;
public function __construct($type)
{
$this->type = $type;
}
}
class BModule extends Module
{
}
class CModule extends BModule
{
}
class A
{
private $module;
public function __construct(Module $module)
{
echo 'Set module for '.__CLASS__.' to '.$module->type . PHP_EOL;
echo "<br>";
$this->module = $module;
}
public function getModule()
{
echo "I (as " . __CLASS__ . ") have a module of type " . $this->module->type;
return $this->module->type;
}
}
class B extends A
{
}
$m = new Module('base-module');
$bm = new BModule('bi-module');
echo "<br>--------A---------<br>";
$a = new A($m);
echo "<br>A is of type " . $a->getModule();
echo "<br>--------B---------<br>";
$b = new B($bm);
echo "<br>B is of type " . $b->getModule();
class A
{
private $module;
public function __construct(Module $module)
{
echo 'Set module for '.__CLASS__.' to '.$module->type . PHP_EOL;
echo "<br>";
$this->module = $module;
}
}
class B extends A
{
public function __construct()
{
parent::__construct(new Module()); // call the parent (which is A)
}
}
这是预期的功能,尽管B继承了A的所有方法,但它们不是在B的上下文中调用的,而是在A的上下文中调用的。因此调用了A构造函数。这意味着,即使对象被扩展,在中定义的函数也可以访问对象的属性。但是,在A中定义的方法无法访问B的属性,这似乎是您的理解
因此,简短地回答您的问题:
不,函数总是在定义它们的上下文中调用,而不是从调用它们的上下文中调用
PHP将一直检查继承链,看看它是否正确。可以假定一个类的任何子类都具有相同的函数。因此,如果B扩展了A,当B的类型提示A时,您可以使用B或A作为参数,但仅当B的类型提示B时才使用B
Ad 1:不,被调用方法的上下文是方法(在本例中是构造函数)的声明位置。如果上下文是classB
,那么任何人都可以通过扩展它来破坏您的类
看看这个例子:
<?php
class Module
{
public $type;
public function __construct($type)
{
$this->type = $type;
}
}
class BModule extends Module
{
}
class CModule extends BModule
{
}
class A
{
private $module;
public function __construct(Module $module)
{
echo 'Set module for '.__CLASS__.' to '.$module->type . PHP_EOL;
echo "<br>";
$this->module = $module;
}
public function getModule()
{
echo "I (as " . __CLASS__ . ") have a module of type " . $this->module->type;
return $this->module->type;
}
}
class B extends A
{
}
$m = new Module('base-module');
$bm = new BModule('bi-module');
echo "<br>--------A---------<br>";
$a = new A($m);
echo "<br>A is of type " . $a->getModule();
echo "<br>--------B---------<br>";
$b = new B($bm);
echo "<br>B is of type " . $b->getModule();
class A
{
private $module;
public function __construct(Module $module)
{
echo 'Set module for '.__CLASS__.' to '.$module->type . PHP_EOL;
echo "<br>";
$this->module = $module;
}
}
class B extends A
{
public function __construct()
{
parent::__construct(new Module()); // call the parent (which is A)
}
}
在这种情况下,您必须依赖于超类中getA()
方法的实现:
class b extends a
{
public function getA()
{
return parent::getA() . "_suffix"; // ok, we are depending on the super class implementation
}
}
我有点困惑。所以,如果我有一些简单的东西,比如class a{getClass(){return get_class($this);}}}
和class b扩展了a{}
,那么对b的实例调用getClass()
不会返回a?(因为正如我们所说的,该方法是在父a的上下文中继承和执行的)。很抱歉代码的格式错误,也很抱歉最终会出现愚蠢的问题。没错,它将返回B而不是A。这是因为函数是在A的上下文中调用的,但$This引用的实际对象仍然是B类型