继承中的私有访问

时间:2017-11-08 10:40:42

标签: php class inheritance private-members

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的私有成员。这不违反私人访问规则吗?

使用父类变量时出错,但是使用子类变量!!任何人都可以解释原因吗?

5 个答案:

答案 0 :(得分:19)

<强> TLDR;

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

<强>解释

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

<?php

class Person {
    // private $age;
}

class Employee extends Person {
}

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

$emp->age = 10行中,我们创建了名为$emp的{​​{1}}对象的新属性,并为其指定了值age

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

10

答案 1 :(得分:3)

您从对象($emp->age = 30;)分配$emp

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

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

所以在你的示例中$emp->age,其中age不被视为任何类的成员变量,因为它没有在其中定义。

如果你尝试任何不属于任何类的成员的变量名,你会更清楚。你也会得到他们的结果。

例如,尝试以下代码:

$emp->age_tmp = 30;

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

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

没有任何联系

DEMO

答案 2 :(得分:2)

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

如果超级班有私人领域。那个字段并不存在于儿童中。在您的代码中,员工没有字段年龄。 $emp->age = 42;是有效的PHP代码。

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

人的私人领域不存在于儿童中。

OOP php visibility

答案 3 :(得分:1)

在PHP中,您可以在代码中的任何位置创建属性。变量&#34; age&#34;不是父类的。你可以尝试这个,如果你想要

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

显示的变量属于员工类,它是本地的。

答案 4 :(得分:1)

顺便说一句,如果你想从一个实例创建私有属性$age,你可以这样做:

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

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

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

现在尝试一下,为$age分配一个值。

3v4l.org