ホームページ >バックエンド開発 >PHPチュートリアル >PHP OOP 部分構成と継承および依存関係の注入

PHP OOP 部分構成と継承および依存関係の注入

Patricia Arquette
Patricia Arquetteオリジナル
2025-01-05 00:14:41207ブラウズ

PHP OOP Part-Composition vs Inheritance and Dependency Injection

このシリーズでは、PHP オブジェクト指向プログラミング (OOP) の基礎について説明します。コンテンツは連続したパートに編成され、それぞれが特定のトピックに焦点を当てます。初心者または OOP の概念に慣れていない場合、このシリーズは段階的にガイドできるように設計されています。 このパートでは、PHP における合成と継承および依存関係の挿入について説明します。一緒に PHP OOP を学ぶ旅を始めましょう!

構成と継承

オブジェクト指向プログラミングにおける親クラスと子クラスの関係についてはすでに学習しており、子クラスが親クラスを継承し、そこからすべてにアクセスできることがわかりました。これは継承として知られています。

一方、コンポジションとは、親クラスを継承するのではなく、子クラスのプロパティ値として割り当てることを指します。これにより、親クラスからすべてにアクセスできます。これは合成として知られています。

以下は、構成と継承を説明する例です。

コード例

class Link
{
   public string $name;
   public string $type;

   public function create($name, $type)
   {
      $this->name = $name;
      $this->type = $type;
   }

   public function show()
   {
      echo "name: $this->name, type: $this->type";
   }
}


// Inheritance example
class ShoLink extends Link
{
   // other functionalities
}


// Composition example
class User
{
   public Link $link;

   public function __construct()
   {
      $this->link = new Link();
   }
   // other functionalities
}

$user = new User();
$user->link->create("Jamir", "Short");

最初の例では、ShoLink クラスが Link クラスを継承していることがわかります。一方、2 番目の例では、User クラスは Link クラスを継承しません。代わりに、Link クラスのインスタンスをそのプロパティの 1 つに割り当てます。その結果、両方の子クラスの Link クラスからすべてにアクセスできるようになります。

ここで、継承を使用してすべてにアクセスできるのであれば、なぜ合成を使用する必要があるのでしょうか?という疑問が生じるかもしれません。結局のところ、合成では、追加のプロパティを宣言し、構築を通じてその値を設定する必要があります。これは余分な作業のように思えますが、合成を使用する利点は何でしょうか?

そうですね、継承により、親クラス内のすべてのものに子クラスからアクセスできるようになることがわかりました。したがって、親クラスの特定のメソッドを使用したくない場合でも、親クラスの一部のプロパティやメソッドが子クラスで必要ない場合でも、それらがパブリック メンバーまたは保護されたメンバーであれば、子クラスでアクセスできるようになります。 .

この問題を解決するには、合成を使用します。合成を使用すると、親クラスの必要な部分のみを子クラスでアクセスできるようにすることができます。別の例でこれをさらに明確にしてみましょう。

Link クラスをよく見ると、show メソッドがあることがわかります。このメソッドを使用すると、ShoLink クラスで作成されたリンクを直接表示できます。

しかし、User クラスでユーザー用に作成されたリンクを誰も直接表示できないようにしたい場合はどうすればよいでしょうか?代わりに、ユーザーのリンクをプロフィールの横に表示することもできます。

これが、User クラスで Link クラスを継承する代わりに、合成を通じてアクセスしている理由です。その結果、誰も User クラスを介してユーザーのリンクを直接表示することはできませんが、ShoLink クラスのリンクを直接表示することはできます。

継承より合成を優先する

これで、合成について、また特定の問題を解決するために継承の代わりにそれを使用する場合についてある程度理解できました。 OOP には「継承よりも合成を優先する」という原則があり、これは継承よりも合成を優先することを意味します。言い換えれば、親クラスからすべてにアクセスする必要がない子クラスの場合は、常に継承よりも合成を優先する必要があります。

ここで、疑問が生じます。いつ合成を使用し、いつ継承を使用するかをどのように決定するのでしょうか?

この場合、次の 2 種類の関係に基づいて決定する必要があります。

  1. は -> です。関係。関係が「である」場合は、継承を使用する必要があります。
  2. には -> があります。関係。関係が「ある」場合は、合成を使用する必要があります。

コード例

class Link
{
   public string $name;
   public string $type;

   public function create($name, $type)
   {
      $this->name = $name;
      $this->type = $type;
   }

   public function show()
   {
      echo "name: $this->name, type: $this->type";
   }
}


// Inheritance example
class ShoLink extends Link
{
   // other functionalities
}


// Composition example
class User
{
   public Link $link;

   public function __construct()
   {
      $this->link = new Link();
   }
   // other functionalities
}

$user = new User();
$user->link->create("Jamir", "Short");

上記の ShoLink クラスの例を見ると、ShoLink クラスが Link クラスから継承していることがわかります。したがって、それらの間の関係を定義するとしたら、ShoLink は本質的にリンクの一種であるため、その関係は ShoLink はリンクであるということになります。

コード例

// Inheritance example
class ShoLink extends Link
{
   // other functionalities
}

ここで、上記の User クラスの例を見ると、User クラスが Link クラスとの合成を使用していることがわかります。したがって、これらの間の関係を定義するとしたら、ユーザーはリンクではないため、その関係は「ユーザーはリンクを持っている」ということになりますが、ユーザーはリンクを持つことも、リンクを所有することもできます。

それぞれをいつ使用するか、さまざまな状況でどれを優先するかなど、構成と継承についてより明確に理解できたと思います。

依存関係の注入

依存関係の注入を理解する前に、まず依存関係とは何かを理解する必要があります。依存関係とは、子クラスが継承または合成によって別のクラスのメンバーを使用することです。その場合、親クラスは子クラスの依存関係になります。

上記の例では、継承の代わりに合成を使用する場合、子クラスでプロパティを宣言し、コンストラクターを介して親クラスのインスタンスをそのプロパティに割り当てる必要があることがわかりました。したがって、User クラスを使用する場合は、User クラスが Link クラスに依存しているため、そのコンストラクターで Link クラスをインスタンス化する必要があります。言い換えれば、Link クラスは User クラスの依存関係です。ここでの問題は、Link クラスのインスタンス化プロセスが User クラス内で密接に結合されていることです。

問題は、Link クラスのインスタンス化が制限されており、User クラスに固有であることです。 Link クラスの代わりに他のクラスを外部から User クラスに渡したい場合、コンストラクターで Link クラスのインスタンスを明示的に作成し、それを Link プロパティに割り当てるため、それはできません。これは密結合依存関係と呼ばれ、この依存関係を外部から変更できないことを意味します。

しかし、コンストラクター内で Link クラスを自分たちでインスタンス化せず、代わりにユーザーに任せる場合、つまりユーザーが User クラスを使用するときに、Link クラスの依存関係を User クラスに渡すことになる場合、問題は次のようになります。解決しました。

以下のコード例を見てみましょう。

コード例

class Link
{
   public string $name;
   public string $type;

   public function create($name, $type)
   {
      $this->name = $name;
      $this->type = $type;
   }

   public function show()
   {
      echo "name: $this->name, type: $this->type";
   }
}


// Inheritance example
class ShoLink extends Link
{
   // other functionalities
}


// Composition example
class User
{
   public Link $link;

   public function __construct()
   {
      $this->link = new Link();
   }
   // other functionalities
}

$user = new User();
$user->link->create("Jamir", "Short");

この例では、User クラスのコンストラクターで Link クラスをインスタンス化する代わりに、Link クラスの依存関係を外部から User クラスに渡していることがわかります。ユーザーを介して依存関係を User クラスに渡すこのプロセスは、依存関係の注入と呼ばれます。言い換えれば、Link クラスの依存関係を外部から注入またはプッシュしています。これは疎結合依存関係として知られており、この依存関係を外部から簡単に変更できることを意味します。

Link クラスにも独自の依存関係がある場合、User クラスを介して外部からその依存関係を注入することもできます。次に、Link クラスのインスタンスを User クラスに注入するだけです。その結果、ユーザーが外部から処理するため、User クラス内の Link クラスの依存関係について心配する必要がなくなります。

以下のコード例を見てみましょう。

コード例

// Inheritance example
class ShoLink extends Link
{
   // other functionalities
}

このようにすると、外部から必要なだけ依存関係を注入でき、より柔軟になります。今日はここまでです。次のレッスンで話します。

GitHub や Linkedin で私とつながることができます。

以上がPHP OOP 部分構成と継承および依存関係の注入の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。