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