继承中的私有访问

Private access in inheritance

class  Person {
    public  $name;
    private $age; //private access
}

class Employee extends Person{
    public $id;
    public $salary; //class property   
}

$emp = new Employee(); 
$emp->name="ABCD";
$emp->age = 30;
$emp->id=101;
$emp->salary=20000;

echo "<br/> Name : ".$emp->name;
echo "<br/> Age : ".$emp->age;

在这段代码中,子 class 变量 $emp 可以直接访问父 class Person 的私有成员。这不是违反私有访问规则吗?

使用父 class 变量时出错,但与子 class 变量一起使用!!谁能解释一下为什么?

您正在分配 $emp->age = 30; From object($emp).

现在,当您尝试使用对象(不是成员变量)访问任何变量时,它将允许访问并创建局部作用域

并不是说它不被视为那个特定 class 的成员变量。

因此在您的示例 $emp->age 中,年龄不被视为任何 class 的成员变量,因为它未在其中定义。

如果您尝试任何不属于 class 的任何变量名称,您会更清楚地了解。你也会为他们得到结果。

例如尝试下面的代码:

$emp->age_tmp = 30;

echo "<br/> Age : ".$emp->age_tmp;

所以问题不在于范围,而是它会为该变量创建其他副本。 $emp->agePerson class age

没有任何关系

DEMO

在PHP中,您可以在代码的任意位置创建属性。变量 "age" 不是父 class 的变量。如果你想,你可以试试这个

<?php

class  Person {
public  $name = "Scare";
private $age = 30; //private access
protected $gender = "Man";
}

class Employee extends Person{
public $id = 20;
public $salary; //class property   
}

$emp = new Employee(); 
echo $emp->id;
echo $emp->name;
echo $emp->age;
$emp->age = "10";
echo $emp->age;
echo $emp->gender;
?>

显示的变量who属于员工class,是本地的

TLDR;

$emp->age = 30 不调用 parent 私有成员 age,它动态创建新的 child object 属性 age .

说明

看起来像个错误,不是吗?首先,我们把parent的私有成员注释掉:

<?php

class Person {
    // private $age;
}

class Employee extends Person {
}

$emp = new Employee();
$emp->age = 10;
echo $emp->age . "\n";
//out: 10

在行 $emp->age = 10 中,我们创建了名为 age$emp object 的新 属性 并为其赋值 10

当您将 parent 的成员定义为私有时,children 根本看不到该成员:

<?php

class  Person {
    private $age;

    function __construct() {
        $this->age = 30;
    }

    public function printAge()
    {
        echo sprintf("Parent::age = %s\n", $this->age);
    }
}

class Employee extends Person {
    private $age;

    function __construct() {
        parent::__construct();
        $this->age = 10;
    }

    public function printAge()
    {
        echo sprintf("Employee::age = %s\n", $this->age);
        parent::printAge();
    }
}

$emp = new Employee();
$emp->printAge();

//out:
//Employee::age = 10
//Parent::age = 30

您可以定义 $object = new stdClass(); 并使用语法 $object->field = "value";.

赋值

如果超级 class 有一个私有字段。该字段在儿童中不存在。在您的代码中,员工没有年龄字段。 $emp->age = 42; 是有效的 php 代码。

要在 Employee 中保持年龄隐私,您需要将字段设置为受保护。受保护的字段意味着超级 class 和儿童也是私有的。

人的私有领域,不存在于子领域。

OOP php visibility

顺便说一下,如果您不想从实例创建私有 属性 $age,您不妨这样做:

class  Person {
    public  $name;
    private $age; //private access

    public function __set($age, $value) {
        return false;
    }
}

__set()是一种自动设置新的属性的魔术方法。 在这种情况下,当试图设置 $age 时它将不起作用。

现在试试,给$age赋值。

3v4l.org