继承中的私有访问
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->age
与 Person
class age
没有任何关系
在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 和儿童也是私有的。
人的私有领域,不存在于子领域。
顺便说一下,如果您不想从实例创建私有 属性 $age
,您不妨这样做:
class Person {
public $name;
private $age; //private access
public function __set($age, $value) {
return false;
}
}
__set()
是一种自动设置新的属性的魔术方法。
在这种情况下,当试图设置 $age
时它将不起作用。
现在试试,给$age
赋值。
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->age
与 Person
class age
在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 和儿童也是私有的。
人的私有领域,不存在于子领域。
顺便说一下,如果您不想从实例创建私有 属性 $age
,您不妨这样做:
class Person {
public $name;
private $age; //private access
public function __set($age, $value) {
return false;
}
}
__set()
是一种自动设置新的属性的魔术方法。
在这种情况下,当试图设置 $age
时它将不起作用。
现在试试,给$age
赋值。