PHP class(類別) 是建立 object(物件)的藍圖,定義屬性與方法;object 則是用 new 依照 class 產生的實例,各自保存自己的資料。物件導向(OOP)把相關的資料和操作資料的程式碼放在一起,讓程式不必像咖啡店的桌面一樣,什麼東西都堆在同一區。

這篇用簡單範例帶你理解 class、object、屬性、方法、$this 與封裝。讀完後,你應該能看懂基本 OOP 程式,並開始設計小型類別。

快速參考

概念說明
class定義物件應有的屬性與方法(設計圖)
objectnew ClassName() 建立的實例(成品)
屬性(property)物件的資料,如 $book->title
方法(method)物件的行為,如 $book->describe()
$this在方法內代表「目前這個物件」
封裝privateprotected 限制外部直接改資料

class 與 object 差在哪?

生活化比喻:class 像設計圖,object 像依照設計圖做出來的成品

Cake 類別描述蛋糕有哪些資料(口味、尺寸)和能做什麼(烘烤)。依照它建立的巧克力蛋糕和草莓蛋糕,是兩個不同的 object。

  • class:定義物件應有的屬性和方法
  • object:class 建立出來的實例,擁有自己的資料
  • 實例化:用 new 依照 class 建立 object 的過程

建立第一個 class

<?php

class Cake
{
	public $flavor;
	public $size;

	public function bake()
	{
		echo '正在烘烤 ' . $this->flavor . ' 口味的蛋糕。';
	}
}
  • flavorsize屬性,保存物件資料
  • bake()方法,描述物件行為
  • $this 代表「目前正在呼叫這個方法的物件」

new 建立 object

$chocolateCake = new Cake();
$chocolateCake->flavor = '巧克力';
$chocolateCake->size = '大';

$chocolateCake->bake();

箭頭 -> 用來存取物件的屬性或方法。同一個 class 可以建立多個彼此獨立的 object:

$chocolateCake = new Cake();
$chocolateCake->flavor = '巧克力';

$strawberryCake = new Cake();
$strawberryCake->flavor = '草莓';

$chocolateCake->bake();  // 巧克力
$strawberryCake->bake();  // 草莓

實戰範例:Book 與 Bookshelf

<?php

class Book
{
	public $title;
	public $author;

	public function describe()
	{
		return $this->title . ',作者:' . $this->author;
	}
}

$book = new Book();
$book->title = '哈比人';
$book->author = 'J. R. R. 托爾金';

echo $book->describe();

describe() 透過 $this 取得目前物件的資料,不必另外傳入 $book

物件組合:一個 object 管理多個 object

<?php

class Bookshelf
{
	public $books = [];

	public function addBook(Book $book)
	{
		$this->books[] = $book;
	}

	public function listBooks()
	{
		foreach ($this->books as $book) {
			echo $book->describe() . PHP_EOL;
		}
	}
}

$bookshelf = new Bookshelf();
$bookshelf->addBook($book);
$bookshelf->listBooks();

Bookshelfbooks 陣列放著多個 Book object——這就是物件組合(composition)

封裝與可見性

前面用 public,代表類別外也能直接讀寫。實務上通常限制外部直接改資料:

修飾符類別內子類別類別外
public
protected
private
<?php

class Book
{
	private $title;

	public function setTitle($title)
	{
		$this->title = $title;
	}

	public function getTitle()
	{
		return $this->title;
	}
}

$book = new Book();
$book->setTitle('哈比人');

echo $book->getTitle();

這就是封裝:把資料和操作規則放在一起,限制外部直接碰觸內部狀態。詳細對照見 存取修飾符

常見問題

Q:class 和 object 一定要一起用嗎?
A:class 是定義,object 是執行時的實例。沒有 new 建立 object,class 只是規格,不會自己跑起來。

Q:$thisself 差在哪?
A:$this 指向目前物件實例;self 指向類別本身(常用於靜態成員)。初學先掌握 $this 即可。

Q:什麼時候該用 OOP?
A:當多組資料和函式明顯屬於同一種「事物」時——例如訂單、使用者、書籍。簡單腳本不必硬套 class。

Q:下一步學什麼?
A:存取修飾符try catchComposerSOLID

結語

PHP OOP 的核心詞彙:

  • class 定義屬性與方法
  • object 是 class 的實例
  • new 建立 object
  • $this 在方法內代表目前物件
  • 封裝 透過可見性控制資料存取

當程式裡有許多互相關聯的資料和函式時,問自己:「這些是不是屬於同一種事物?」如果是,就可能是設計 class 的好時機。

參考資料