PHPにおけるOOPの継承時のプライベートプロパティの問題
プライベートプロパティが継承されないという事実は、 予期せぬ問題を引き起こす可能性があります。 例を見てみましょう。 以下のようなプライベートプロパティを持つ 親クラスがあるとします:
<?php
class User {
private $age;
public function setAge($age) {
$this->age = $age;
}
public function getAge() {
return $this->age;
}
}
?>
子クラスで、年齢を1つ増やすメソッドを 作成しようとしたとします。 しかし、親のプライベートプロパティを 変更しようとするとエラーになります:
<?php
class Student extends User {
public function incAge() {
$this->age++; // エラー
}
}
?>
子クラスでプライベートプロパティ $age を
宣言するとエラーは解消されます:
<?php
class Student extends User {
private $age;
public function incAge() {
$this->age++;
}
}
?>
ここに罠が潜んでいるのです! 実際には、親クラスと子クラスに それぞれ独立した2つのプライベートプロパティが 生成されています。 つまり、親クラスのメソッドは親クラスのプロパティを変更し、 子クラスのメソッドは子クラスのプロパティを変更する ということになります。
この問題には実際に解決策があります。 親クラスのプライベートプロパティは、 その親クラスのメソッドを介して 操作する必要があります。 この考え方に従ってコードを書き直してみましょう:
<?php
class Student extends User {
public function incAge() {
$age = $this->getAge();
$age++;
$this->setAge($age);
}
}
?>
以下のように簡略化できます:
<?php
class Student extends User {
public function incAge() {
$this->setAge($this->getAge() + 1);
}
}
?>
以下のコードでは、子クラスで親クラスのメソッドが オーバーライドされています。 このコードの問題点を修正してください:
<?php
class User {
private $name;
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
class Employee extends User {
public function setName($name) {
if (strlen($name) > 0) {
$this->name = $name; // エラー
}
}
}
?>