web-dev-qa-db-ja.com

継承におけるプライベートアクセス

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行に、ageという名前の$empオブジェクトの新しいプロパティを作成し、それに値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
Ivan Kalita

$emp->age = 30; From object($emp)を割り当てています。

これで、オブジェクト(メンバー変数ではない)を使用して変数にアクセスしようとすると、アクセスが許可され、ローカルスコープが作成されます

その特定のクラスのメンバー変数として扱われないわけではありません。

したがって、ここでの例では$emp->ageであり、年齢はクラスで定義されていないため、どのクラスのメンバー変数とも見なされません。

どのクラスのメンバーでもない変数名を試してみると、より明確なアイデアが得られます。あなたも彼らのために結果を得るでしょう。

たとえば、以下のコードを試してください。

$emp->age_tmp = 30;

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

したがって、問題はスコープに関するものではありませんが、その変数の他のコピーが作成されます。 $emp->agePersonクラスageとは何の関係もありません

[〜#〜]デモ[〜#〜]

3
B. Desai

$object = new stdClass();を定義し、構文$object->field = "value";で値を割り当てることができます。

スーパークラスにプライベートフィールドがある場合。そのフィールドは子供には存在しません。コードでは、従業員にはフィールド年齢がありません。そして、$emp->age = 42;は有効なphpコードです。

従業員の年齢を非公開にするには、フィールドを保護対象として設定する必要があります。保護されたフィールドとは、スーパークラスと子供のためにプライベートであることを意味します。

人の私有地は、子供には存在しません。

OOP phpの可視性

2
sensorario

PHPでは、コード内のどこにでも属性を作成できます。変数「age」は親クラスの変数ではありません。必要に応じてこれを試すことができます

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

Displayである変数はemployeeクラスに属し、ローカルです。

1
Y.op