Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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_Type Hinting - Fatal编程技术网

构造函数可以访问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中处理继承时,我发现自己缺乏一些知识,主要是关于构造函数私有属性

让我们以这段代码为例:

<?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:不,被调用方法的上下文是方法(在本例中是构造函数)的声明位置。如果上下文是class
    B
    ,那么任何人都可以通过扩展它来破坏您的类

    看看这个例子:

    <?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类型