Php 继承中的私有访问 班级人员{ 公共名称; private$age;//私有访问 } 类雇员扩展个人{ 公费$id; public$salary;//类属性 } $emp=新员工(); $emp->name=“ABCD”; $emp->age=30; $emp->id=101; $emp->工资=20000; echo“名称:“.$emp->名称; 回声“年龄:.$emp->Age;

Php 继承中的私有访问 班级人员{ 公共名称; private$age;//私有访问 } 类雇员扩展个人{ 公费$id; public$salary;//类属性 } $emp=新员工(); $emp->name=“ABCD”; $emp->age=30; $emp->id=101; $emp->工资=20000; echo“名称:“.$emp->名称; 回声“年龄:.$emp->Age;,php,class,inheritance,private-members,Php,Class,Inheritance,Private Members,在此代码中,子类变量$emp可以直接访问父类个人的私有成员。这是否违反了私有访问规则 使用父类变量时会出现错误,但使用子类变量时会出现错误!!有人能解释一下原因吗?您正在分配$emp->age=30来自对象($emp) 现在,当您试图使用对象(不是成员变量)访问任何变量时,它将允许访问并创建局部范围 并不是说它不被视为该特定类的成员变量 所以,在你的例子中,代码> $EMP->年龄< /代码>,其中年龄不被认为是任何类别中的成员变量,因为它没有定义。 如果您尝试任何不是任何类的成员的变量名,您将

在此代码中,子类变量
$emp
可以直接访问父类
个人的私有成员。这是否违反了私有访问规则


使用父类变量时会出现错误,但使用子类变量时会出现错误!!有人能解释一下原因吗?

您正在分配
$emp->age=30来自对象(
$emp

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

并不是说它不被视为该特定类的成员变量

所以,在你的例子中,代码> $EMP->年龄< /代码>,其中年龄不被认为是任何类别中的成员变量,因为它没有定义。

如果您尝试任何不是任何类的成员的变量名,您将更清楚地了解这一点。你也会为他们得到结果

例如,请尝试以下代码:

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;
$emp->age\u tmp=30;
回声“
年龄:.$emp->Age\u tmp;
所以问题不在于作用域,而在于它将为该变量创建另一个副本<代码>$emp->age
人员
年龄


在PHP中,您可以在代码中的任何位置创建属性。变量“age”不是父类的变量。如果你愿意,你可以试试这个

$emp->age_tmp = 30;

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

显示的变量属于employee类,并且是本地变量。

TLDR

$emp->age=30
不调用父私有成员
age
,它动态创建新的子对象属性
age

解释

看起来像只虫子,不是吗?首先,让我们评论一下家长的私人成员:

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

您可以定义
$object=new stdClass()并使用语法
$object->field=“value”分配值

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

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

个人的私人领域,在儿童中不存在


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

<?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
\uuu set()
是一种神奇的方法,可以自动设置新属性。 在这种情况下,当试图设置
$age
时,它将不起作用

现在尝试一下,为
$age
指定一个值


如果您
var\u dump($emp)
<代码>[“年龄”:“个人”:私人]=>NULL[“年龄”]=>int(30)
。。。私有
Person::age
为空,但创建了一个新的公共
Employee::age
,并将其设置为30。出于安全原因,我不会直接返回属性。这是一个非常有价值的建议。谢谢!!但是,您可能希望抛出一个异常,而不是简单地返回
false
(这可能会让您稍后感到头疼)。该字段存在于儿童中……他们通常无法看到或访问它。差异显著。
<?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
class  Person {
    public  $name;
    private $age; //private access

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