doureng6738 2014-10-15 17:00
浏览 45

构造函数可以在PHP中访问父私有属性吗?

When dealing with inheritance in PHP I found some lack of knowledge, mainly about constructors and private properties.

Let's take this code as example:

<?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();

Some questions:

  1. shouldn't B construction call the constructor in the context of B? (and so I would expect it to fail cause it didn't inherited the private property $module)
    • or PHP would simply call the A constructor, using/referencing methods and properties from A? (including the private ones)
  2. I can pass to $b either a Module or a BModule object; this is because BModule is a child of Module. Is PHP checking some inheritance chain (checking the parents) of the passed object when verifying the type hinting?
    • so can I pass to the constructor either an object of type Module or BModule or CModule?

And this is another example:

<?php


class a
{
    private $a;
    protected $a_copy;

    public function __construct($a_value)
    {
        $this->a = $a_value;
        $this->a_copy = $this->a;
    }

    public function getA()
    {
        return $this->a;
    }
    public function getCopyA()
    {
        return $this->a;
    }
}

class b extends a
{
}


$a = new a('value for a');
$b = new b('value for b');
echo "<br>-----A-----<br>";
echo $a->getA()."<br>";
echo $a->getCopyA()."<br>";
echo "<br>-----B-----<br>";
echo $b->getA()." (I would expect to have no access to \$a)<br>";
echo $b->getCopyA()."<br>";

Being the property $a private, I would expect to not be able to access it or do anything with it from the class b. It is a little bit non-sense for my actual understanding.

  • 写回答

2条回答 默认 最新

  • douweibiao8471 2014-10-15 17:18
    关注

    This is expected functionality, although B inherits all of the methods of A, they're not called in the context of B, they're called in the context of A. So the A constructor is called. This means that functions defined in A can access A's properties even when the object is extended. Methods defined in A cannot access properties of B however, which appears to be your understanding.

    So to shortly answer your questions:

    1. No, functions are always called in the context of where they are defined, not from where they are called.
    2. PHP will check all the way down the inheritance chain to see if it's correct. Any child of a Class can be assumed to have the same functions. So if B extends A, You can use either B or A as a parameter when it's type-hinted to A, but only use B if it's type-hinted to B
    评论

报告相同问题?

悬赏问题

  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记