Частный доступ в наследство

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 непосредственно. Разве это не нарушение правила частного доступа?

Выдает ошибку при использовании родительской переменной класса, но работает с дочерней переменной класса !! Кто-нибудь может объяснить почему?

15

Решение

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
19

Другие решения

Вы назначаете $emp->age = 30; С объекта ($emp).

Теперь, когда вы пытаетесь получить доступ к любой переменной, используя объект (который не является переменной-членом), это позволит получить доступ и создать локальную область видимости.

Не то чтобы он не обрабатывался как переменная-член этого конкретного класса.

Так вот в вашем примере $emp->age где возраст не считается членом любого класса, так как он не определен в нем.

Вы получите более ясную идею, если попробуете любое имя переменной, не входящее ни в один из классов. Вы получите результат и для них.

Например, попробуйте следующий код:

$emp->age_tmp = 30;

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

Так что проблема не в области видимости, а в том, что она создаст другую копию для этой переменной. $emp->age не имеет никакого отношения к Person учебный класс age

DEMO

3

Вы можете определить $object = new stdClass(); и назначить значения с синтаксисом $object->field = "value";,

Если у суперкласса есть личное поле. Это поле НЕ СУЩЕСТВУЕТ у детей. В вашем коде сотрудника нет поля возраста. А также $emp->age = 42; действительный код php.

Чтобы сохранить возраст закрытым в Employee, необходимо установить поле как защищенное. Защищенные поля означает, что это личное для суперкласса, а также для детей.

Частные поля людей, нет у детей.

ООП php видимость

2

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

Переменная, которая отображается, принадлежит классу сотрудников и является локальной.

1

Кстати, если вы хотите частную собственность $age не может быть создан из экземпляра, вы могли бы сделать это:

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

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

__set() это магический метод, который автоматически устанавливает новое свойство.
В этом случае это не будет работать, когда $age пытается быть установлен.

Теперь попробуйте, присвойте значение $age,

3v4l.org

1
По вопросам рекламы [email protected]