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
мы создали новое свойство $emp
названный объект age
и присвоил ему значение 10
,
Когда вы определяете члена своего родного как личного, дети вообще не видят этого члена:
<?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
Вы назначаете $emp->age = 30;
С объекта ($emp
).
Теперь, когда вы пытаетесь получить доступ к любой переменной, используя объект (который не является переменной-членом), это позволит получить доступ и создать локальную область видимости.
Не то чтобы он не обрабатывался как переменная-член этого конкретного класса.
Так вот в вашем примере $emp->age
где возраст не считается членом любого класса, так как он не определен в нем.
Вы получите более ясную идею, если попробуете любое имя переменной, не входящее ни в один из классов. Вы получите результат и для них.
Например, попробуйте следующий код:
$emp->age_tmp = 30;
echo "<br/> Age : ".$emp->age_tmp;
Так что проблема не в области видимости, а в том, что она создаст другую копию для этой переменной. $emp->age
не имеет никакого отношения к Person
учебный класс age
Вы можете определить $object = new stdClass();
и назначить значения с синтаксисом $object->field = "value";
,
Если у суперкласса есть личное поле. Это поле НЕ СУЩЕСТВУЕТ у детей. В вашем коде сотрудника нет поля возраста. А также $emp->age = 42;
действительный код php.
Чтобы сохранить возраст закрытым в Employee, необходимо установить поле как защищенное. Защищенные поля означает, что это личное для суперкласса, а также для детей.
Частные поля людей, нет у детей.
В PHP вы можете создавать атрибуты в любом месте кода. Переменная «возраст» не относится к родительскому классу. ты можешь попробовать это, если хочешь
<?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