Kintarou'sBlog

プログラミング学習中。学習内容のアウトプットや読書で学んだことなど随時投稿!

【PHP】クラスの抽象化

こんにちは😊Kintarouです。

現在エンジニア転職を目指してプログラミング学習中です👨‍🎓
夢はフリーランスエンジニアになって働く人にとって働く事が楽しくなるシステムを作ること!
と、愛する妻と海外移住すること🗽

プログラミングや読んでいる本のことなど、ブログに書いていきます!
twitter : https://twitter.com/ryosuke_angry


今回参考にさせて頂いたサイト様🙇‍♂️ dotinstall.com


子クラスの定義化を強制する

親クラスUserではインスタンスを生成させず、子クラスを作る事を前提としたい場合を考えましょう。
Userクラスをabstract class BaseUserとする事で、インスタンスの生成が出来ない「抽象クラス」にする事が出来ます。(abstract = 概要)

<?php

#abstractとする事で抽象クラスを作ります。
abstract class BaseUser
{
  protected $name;

  public function __construct($name)
  {
    $this->name = $name;
  }

  #こちらもabstractとすることで抽象メソッドとなっています。
  abstract public function profile();
}

class TestUser extends BaseUser
{
  private $pattern;

  public function __construct($name, $pattern)
  {
    parent::__construct($name);
    $this->pattern = $pattern;
  }

  public function profile()
  {
    printf('%s(%s)' . PHP_EOL, $this->name, $this->pattern);
  }
}

$users = [];
$users[0] = new TestUser('Testarou', 'first-pattern');

#TestUser内でprofileメソッドが定義化されているので実行できます。
$users[0]->profile();
#=>Testarou(first-pattern)

※ただ、こうなると元のBaseUserクラス自体がいらないのでは?という疑念が湧きます。
が、抽象クラスのメリットはメソッド名や処理を共通化出来るなど、開発にルールを設ける事ができる事です。
複数人で開発する際には、利用を検討しましょう。

同じ抽象クラスでインスタンスの処理を共通化する

抽象クラスを使い、共通化した場合の利用例です。
TestUserとは別に、本番で利用するProductUserでもインスタンスを作成します。
その後、別のクラスのインスタンスですが共通の動き(profileメソッド)が出来る事を検証します。

<?php

abstract class BaseUser
{
  protected $name;

  public function __construct($name)
  {
    $this->name = $name;
  }

  abstract public function profile();
}

class TestUser extends BaseUser
{
  private $pattern;

  public function __construct($name, $pattern)
  {
    parent::__construct($name);
    $this->pattern = $pattern;
  }

  public function profile()
  {
    printf('%s(%s)' . PHP_EOL, $this->name, $this->pattern);
  }
}

#ProductUserを作ります。
class ProductUser extends BaseUser
{
  private $age;

  public function __construct($name, $age)
  {
    parent::__construct($name);
    $this->age = $age;
  }

  public function profile()
  {
    printf('%s(%d)' . PHP_EOL, $this->name, $this->age);
  }
}

#$usersにTestUser、ProductUserから生成したインスタンスを格納します。
$users = [];
$users[0] = new TestUser('Testarou', 'first-pattern');
$users[1] = new ProductUser('Productarou', 30);

#どちらもBaseUserから型を継承しているので、BaseUser型の$userに対して処理を実行する関数を定義します。
function profileBaseUser(BaseUser $user)
{
  $user->profile();
}

#$usersの要素にforeachでprofileBaseUser(profile)メソッドを実行します。
foreach($users as $user) {
  profileBaseUser($user);
}

#同じメソッドでそれぞれのクラスで定義したインスタンスを実行できました。
#=>Testarou(first-pattern)
#=>Productarou(30)

以上、どなたかの参考になれば幸いです😊