继承中的专用访问


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可以直接访问父类Person的私有成员。这不是违反私有访问规则吗?

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

TLDR;

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

解释

看起来像一个错误,不是吗?首先,让我们注释掉父级的私人成员:

<?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对象的新属性,并为其分配了值 10

当您将父级成员定义为私有成员时,孩子根本看不到此成员:

<?php
class  Person {
    private $age;
    function __construct() {
        $this->age = 30;
    }
    public function printAge()
    {
        echo sprintf("Parent::age = %sn", $this->age);
    }
}
class Employee extends Person {
    private $age;
    function __construct() {
        parent::__construct();
        $this->age = 10;
    }
    public function printAge()
    {
        echo sprintf("Employee::age = %sn", $this->age);
        parent::printAge();
    }
}
$emp = new Employee();
$emp->printAge();
//out:
//Employee::age = 10
//Parent::age = 30

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

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

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

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

如果您尝试任何不是任何类成员的变量名,您将更清楚地了解想法。您还将获得它们的结果。

例如,尝试以下代码:

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

所以问题与范围无关,但它将为该变量创建其他副本。 $emp->age与类age没有任何联系Person

演示

您可以使用

语法$object->field = "value";定义$object = new stdClass();并分配值。

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

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

个人的私域,在孩子身上不存在。

OOP php 可见性

在PHP中,你可以在代码中的任何位置创建属性。变量"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;
?>

显示的变量属于雇员类,它是一个局部变量。

顺便说一下,如果你希望私有属性$age不是从实例创建的,你也可以这样做:

class  Person {
    public  $name;
    private $age; //private access
    public function __set($age, $value) {
        return false;
    }
}

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

现在试试吧,为$age赋值。

3v4l.org

最新更新