メソッドのオーバーライド

継承とインターフェース

スーパークラスとサブクラスを定義し、サブクラスはスーパークラスの機能をそのまま使える便利な機能ですが、継承のメリットはこれだけではありません。継承するとサブクラスではメソッドのオーバーライドを使用して、メソッドを上書きして再定義することができます。

オーバーライドのメリット

スーパクラスのメソッドと同名のメソッドを上書きしつつ再定義できるメリットは、例えば「こういう時はこちらのメソッドを呼び出し」、「別の場合はあちらのメソッドを呼び出す」というように、状況別にメソッドを定義して処理を分けることができます。サブクラスをいくつも作ってそれぞれでオーバーライドをしておくのです。

オーバーライドしてみる

コードを記述して、実際に表示してみて使い方を見てみましょう。

<?php
class User {
  public function show($name, $address){
    print "スーパークラスで情報を表示します。名前は{$name},住所は{$address}です。"."<br>";
  }
}

?>

次にサブクラスを定義しますが、メソッド名は同じにしてください。単にメソッド名を同じにすればオーバーライドできます。

<?php
require_once "User.php";
class UserSub extends User{
  public function show($name, $address){
    print "サブクラスで情報を表示します。名前は{$name},住所は{$address}です。"."<br>";
  }
}

?>

では同じ名前の各クラスのメソッドを呼び出し出力してみましょう。

<html>
<head>
<meta charset="utf-8">
<title>オーバーライド</title>
</head>
<body>
<?php
  require_once 'UserSub.php';
  $user1 = new User();
  $user1->show('佐藤', '東京');
  $user2 = new UserSub();
  $user2->show('鈴木','横浜');

?>
</body>
</html>

同じメソッド名ですがUserSubクラスをインスタンス化した方で呼び出すとUserSubの方のメソッドが呼ばれましたね。同じメソッド名でもインスタンス化した方のメソッドが呼ばれるのが分かります。

オーバーライドする前のメソッドを使用する

先ほどはサブクラスで完全に独自のメソッドを定義しましたが、スーパークラスで定義されたメソッドに機能を付け足したい場合もあります。その場合は以下のようにメソッドを呼び出します。

parent::メソッド名(引数)

アロー演算子ではなく、::であることに注意してください。

実際にコードを記述して確認してみましょう。
また、今回は孫クラスも作成してコードを記述してみます。

<?php
class A {
  public function show(){
    print "これはAクラスのshowメソッド".'<br>';
  }
}
?>
<?php
require_once 'A.php';
  class B extends A {
    public function show(){
      print "これはBクラスのshowメソッド".'<br>';
      parent::show();
    }
  }
?>
<?php
require_once 'B.php';
  class C extends B {
    public function show(){
      print "これはCクラスのshowメソッド".'<br>';
      parent::show();
    }
  }
?>

C.phpをインスタンス化して実行してみましょう。

<html>
<head>
<meta charset="utf-8">
<title>parent</title>
</head>
<body>
<?php
require_once 'C.php';

$obj = new C();
$obj->show();
?>
</body>
</html>

オーバーライドの使用条件

オーバーライドをするための条件は以下の通りです。

  • スーパークラスのメソッド名と同じである
  • スーパークラスのメソッドとパラメーターの構成が同じである
  • アクセス修飾子のレベルは同じか緩いレベルにしか変更できない

継承時のコンストラクター

クラスをインスタンス化する場合は必ずコンストラクターが呼び出されますが、サブクラスをインスタンス化した場合スーパークラスのコンストラクターはどうなるか見ていきましょう。

<?php
class A {
  public $name;
  public function __construct($name){ //コンストラクター
    $this->name = $name;
  }
}
?>
<?php
require_once 'A.php';
  class B extends A {
    public $sex;
    public function __construct($name, $sex){
      parent::__construct($name);//スーパークラスのコンストラクターを呼び出す
      $this->sex = $sex;
    }
  }
?>
<?php
require_once 'B.php';
  class C extends B {
    public $age;
    public function __construct($name, $sex, $age){
      parent::__construct($name, $sex);//スーパークラスのコンストラクターを呼び出す
      $this->age = $age;
    }

    public function show(){
      print "nameプロパティ = {$this->name}" . '<br>'
          . "sexプロパティ = {$this->sex}" . '<br>'
          . "ageプロパティ = {$this->age}";
    }
  }
?>
<html>
<head>
<meta charset="utf-8">
<title>parent</title>
</head>
<body>
<?php
require_once 'C.php';

$obj = new C('佐藤', '男', 20);
$obj->show();
?>
</body>
</html>

コメント

タイトルとURLをコピーしました