Частный доступ в наследство
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
. Это не нарушение правила частного доступа?
Он дает ошибку при использовании переменной родительского класса, но работает с переменной класса child!! Может кто-нибудь объяснить, почему?
Ответы
Ответ 1
TL;DR;
$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
Ответ 2
Вы назначаете $emp->age = 30;
От объекта ($emp
).
Теперь, когда вы пытаетесь получить доступ к любой переменной с помощью объекта (который не является переменной-членом), он позволит получить доступ и создать локальную область
Не то, чтобы он не рассматривался как переменная-член этого конкретного класса.
Итак, вот в вашем примере $emp->age
, где age не рассматривается как элемент varaible любого из классов, поскольку он не определен в нем.
Вы получите более понятную идею, если попробуете любое имя переменной, которое не является членом какого-либо класса. Вы также получите результат для них.
Например, попробуйте под кодом:
$emp->age_tmp = 30;
echo "<br/> Age : ".$emp->age_tmp;
Итак, проблема не в области видимости, но она создаст другую копию для этой переменной. $emp->age
не имеет связи с Person
class age
DEMO
Ответ 3
Вы можете определить $object = new stdClass();
и назначить значения синтаксисом $object->field = "value";
.
Если суперкласс имеет частное поле. Это поле НЕ СУЩЕСТВУЕТ детям. В вашем коде Сотрудник не имеет возраст поля. И $emp->age = 42;
- действительный php-код.
Чтобы сохранить личный возраст в Employee, вам необходимо установить поле как защищенное. Защищенные поля означают, что они являются закрытыми для суперкласса, а также для детей.
Личные частные поля, отсутствуют в детях.
OOP php visability
Ответ 4
В PHP вы можете создавать атрибуты в любом месте кода. Переменная "age" не относится к родительскому классу. u можете попробовать это, если вы хотите
<?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;
?>
Переменная, которая отображается, принадлежит классу employee, а локальная.
Ответ 5
Кстати, если вы хотите, чтобы частное свойство $age
не создавалось из экземпляра, вы также можете это сделать:
class Person {
public $name;
private $age; //private access
public function __set($age, $value) {
return false;
}
}
__set()
- волшебный метод, который автоматически устанавливает новое свойство.
В этом случае он не будет работать, если $age
будет установлен.
Теперь попробуйте, присвойте значение $age
.
3v4l.org