27
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PHPで複数のクラスをextendsしたい

Last updated at Posted at 2013-11-26

PHP5.4以降でtraitという機能が追加されました。
http://php.net/manual/ja/language.oop5.traits.php

クラスAをextendsしてるけど、ここに追加でクラスBとクラスCもextendsしたい、そんな要求を概ね叶えてくれる機能です。

<?php
	// 基底クラス
	class A{
		public function hoge(){
			print('クラスAのメソッドhoge');
		}
	}

	// trait
	trait B{
		public function hoge(){
			print('トレイトBのメソッドhoge');
		}
		public function fuga(){
			print('トレイトBのメソッドfuga');
		}
		public function foo(){
			print('トレイトBのメソッドfoo');
		}
	}

	trait C{
		public function fuga(){
			print('トレイトCのメソッドfuga');
		}
		
		private $int = 1; // プロパティ
	}

	// Aを継承したクラス
	class D extends A{
		// トレイトB,Cを使用
		use B, C{
			// 被っているメソッドfugaはBを使用
			B::fuga insteadof C;
		}
		
		// @Override
		public function foo(){
			print('クラスDのメソッドfoo');
		}
		
		// トレイトのprivateを参照可能
		public function getInt(){
			print($this->int);
		}
	}
		
		// 優先順位は自分自身 > trait > 基底クラス
		$d = new D();
		$d->hoge(); // トレイトBのメソッドhoge
		$d->fuga(); // トレイトBのメソッドfuga
		$d->foo();  // クラスDのメソッドfoo
		$d->getInt(); // 1

interfaceではメソッドの定義しか行えずロジックは書けませんでした。
クラスとはひとつしかextendsできないため、extends A, B, Cができませんでした。
トレイトを使うことによってこれらの問題点を解消し、ロジックを書いたうえで複数extendsのようなことを行うことができるようになります。

トレイト内のprivateな値も参照できていることから、普通のextendsより強い結びつきということがわかります。
実際はもっと単純に、useしたtraitは全部合わせてひとつのクラスと看做すと考えればよいでしょう。
要するにもうPartial classってことでいいよね。

※2013/06/21に自サイトに記載したもの

27
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?