開啟小鈴鐺通知
檢舉內容

跟PHP一起玩轉物件導向:從玩具箱到工具箱-深入類別與物件

閱讀時間約 13 分鐘

第二階段:深入類別與物件

進入到物件導向程式設計的第二階段,我們將更細緻地探討類別和物件的定義,以及如何在 PHP 中運用它們。此外,還會深入了解屬性和方法,特別是訪問控制和靜態成員的運用。

定義類別和物件

即將進入廣告,捲動後可繼續閱讀
為什麼會看到廣告

在上一篇中,類別是由 class 關鍵字後跟類別名稱來定義的。類別可以包含屬性(用於存儲數據)和方法(用於執行操作)。類別的實例化則是通過使用 new 關鍵字來創建類別的物件。

<?php

namespace Rewrite\\ExerciseObjectOriented;

/**
*
* Class Person
* @package Rewrite\\ExerciseObjectOriented
*/
class Person
{
/** @var string 公開屬性-姓名 「任何地方都能存取」 */
public string $name;

/** @var int 保護屬性-年齡 「僅限於此類別及繼承它的子類別內部存取」 */
protected int $age;

/** @var string 私有屬性-性別 「僅限於此類別內部存取」 */
private string $gender;

/** @var string 私有屬性-生日 「僅限於此類別內部存取」 */
private string $birthday;

/** @var string 私有屬性-興趣 「僅限於此類別內部存取」 */
private string $hobby;

/**
* Person constructor.
*
* @param string $name
* @param int $age
*/
public function __construct(string $name = '', int $age = 0, string $gender = '')
{
$this->name = $name;

$this->setAge( $age );

$this->gender = $gender;
}

/**
* 方法-設定年齡的方法「僅限於此類別內部存取」
*
* @param int $age
*/
private function setAge(int $age): void
{
if($age >= 0) {
$this->age = $age;
}
}

/**
* 方法-取得年齡的公開方法
*
* @return int
*/
public function getAge(): int
{
return $this->age;
}

/**
* 方法-設定生日的私有方法
*
* @param string $birthday
*/
private function setBirthday(string $birthday): void
{
$this->birthday = $birthday;
}

/**
* 方法-取得生日的公開方法
*
* @return string
*/
public function getBirthday(): string
{
return $this->birthday;
}

/**
* 方法-設定性別的公開方法
*
* @param string $gender
*/
protected function setGender(string $gender): void
{
$this->gender = $gender;
}

/**
* 方法-設定性別的公開方法
* 獲取性別的公開方法
*
* @return string
*/
public function getGender(): string
{
// 判斷性別是否為 m 或 f
if( in_array($this->gender, ['m', 'f']) ){

if ($this->gender === 'm') {
return '男性';
} else {
return '女性';
}
}

return '不透露';
}

/**
* 方法-設定興趣的公開方法
*
* @param string $hobby
*/
public function setHobby(string $hobby): void
{
$this->hobby = $hobby;
}

/**
* 方法-取得興趣的公開方法
*
* @return string
*/
protected function getHobby() {
return $this->hobby;
}
}

屬性與方法

  • 屬性(Properties):在 PHP 的類別裡頭,屬性就是用來記錄這個類別或者是由這個類別產生出來的物件相關的資訊,可以想像成是類別或物件的"特徵"。這些屬性可以設定成不同的存取權限,控制誰可以使用這些屬性。
    • 公開(Public):設定為公開的屬性,意思就是誰都可以自由地來用,無論是在類別內部、繼承這個類別的子類別,還是在類別外部的其他地方。
    • 保護(Protected):保護的屬性則是比較挑剔一點,它只允許這個類別自己,以及繼承這個類別的子類別使用,其他人則是不行進入的。
    • 私有(Private):私有的屬性則是最為嚴格的,它只允許在這個類別的內部使用,連繼承這個類別的子類別都無法存取,保證了這個屬性的隱私性和專一性。

Public, Protected, Private,這就是PHP的存取控制(Visibility),透過這樣的設計,可以幫助我們更好地管理程式碼,避免不小心修改到不應該改的部分,同時也確保了資料的安全性和程式碼的可讀性。在 PHP 中運用這些存取控制,就能夠讓我們的程式碼更為清晰、結構化,也更加容易維護和擴展。

// 創建Person物件
$person = new Person("John", 30, 'M');

// 存取公開屬性
echo "姓名: " . $person->name . "<br>";

// 透過公開方法設置和獲取保護屬性
$person->setAge(30);
echo "年齡: " . $person->getAge() . "<br>";

// 直接存取私有屬性會導致錯誤
// echo $person->gender; // 錯誤

// 透過公開方法獲取私有屬性的值
echo "性別: " . $person->getGender() . "<br>";
  • 方法(Methods):方法是在類別內部定義的函數,用於執行特定的操作。方法也可以定義為公開、保護或私有。
<?php

namespace Rewrite\\ExerciseObjectOriented;

/**
* 員工
* Employee 繼承 Person
*
* Class Employee
* @package Rewrite\\ExerciseObjectOriented
*/
class Employee extends Person
{
/** @var string 員工職位 */
public string $position;

public function __construct($name, $age, $gender, $position)
{
parent::__construct($name, $age, $gender); // 呼叫父類別的構造函數
$this->position = $position;
}

/**
* 方法-取得年齡的公開方法<覆寫父類別的公開方法>
*
* @return string
*/
public function getAge(): int
{
return $this->age; // 可以存取保護屬性
}

/**
* 方法-取得興趣的公開方法<訪問父類別的私有屬性會照成錯誤>
*
* @return string
*/
public function getHobby()
{
// return $this->hobby; // 錯誤:無法直接訪問私有屬性

return "Hobby: " . parent::getHobby(); // 透過父類別的公開方法訪問
}
}

我們可以透過UML圖,更直覺的知道 getHobby 在父層是保護(protected),到了子層進行複寫(Override),改變了控制權,變成了公開(public),但在內部還是可以呼叫父層的getHobby()方法,這就是存取權限的變化。

raw-image
zoomable

存取修飾子(Visibility):子類方法的存取修飾子不能比父類方法更嚴格。例如,如果父類的方法是 public,子類不能將覆寫的方法設置為 privateprotected


靜態屬性與方法

在 PHP 中,靜態屬性和方法屬於類別本身,而不是類別的某個實例。可以通過類別名稱直接訪問靜態屬性和方法,而不需要創建類別的實例。

/**
* 靜態屬性和靜態方法示範
*
* Class Math
* @package Rewrite\\ExerciseObjectOriented
*/
class Math
{
/** @var float */
public static $pi = 3.14159; // 靜態屬性

/**
* @param int $num
* @return int
*/
public static function square($num)
{ // 靜態方法
return $num * $num;
}
}

echo Math::$pi; // 輸出 3.14159
echo Math::square(4); // 輸出 16

看到這邊,會不會有一種靜態方法看起來很方便的感覺呢?

使用靜態方法確實帶來一些方便,比如不需要實例化物件就能調用方法,這在某些情況下可以簡化代碼,減少資源消耗。但是,過度依賴靜態方法也有其缺點,這些缺點主要包括:

  1. 減少靈活性:靜態方法屬於類而非實例,這限制了它們的使用。你不能在靜態方法中訪問類的實例變量或實例方法,這意味著它們不能使用類的狀態或行為。
  2. 難以進行測試:靜態方法由於不依賴於類的實例,因此在單元測試中可能難以模擬和測試。這可能導致測試代碼的維護變得複雜和困難。
  3. 違反物件導向設計原則:過度使用靜態方法可能會導致代碼違反物件導向的設計原則,如封裝和多態性。物件導向程式設計鼓勵通過物件實例來管理和操作數據,使得程式更加模組化和可重用。
  4. 增加代碼間的耦合度:靜態方法容易被其他類直接調用,這可能導致高耦合,使得代碼修改和擴展變得更加困難,並影響其可維護性。

因此,雖然靜態方法在某些情境下很有用(例如工具類或單例模式),我們應該根據具體情況選擇是否使用靜態方法。

一般來說,如果一個方法不需要訪問或修改物件的狀態,那麼將其設計為靜態方法是合適的。但如果方法與物件的狀態緊密相關,則應該使用實例方法。這樣可以保持程式的靈活性和可維護性,並符合物件導向程式設計的原則。

最後

透過這個階段的學習,我們能夠掌握如何在 PHP 中定義和使用類別、物件、屬性和方法,並了解訪問控制及靜態成員的概念和用法。這些都是物件導向程式設計中的核心元素。

Candy-avatar-img
Candy和其他 2 人喜歡這篇
這是一系列以軟體開發為主題的輕鬆分享,內容涵蓋了技術選擇、開發經驗、實戰應用等多方面的議題。無論是如何在眾多框架中做出選擇,還是如何應對技術轉移的挑戰,這裡有幽默、有趣的對話風格,將複雜的技術問題轉化為易懂的故事。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
本階段介紹物件導向程式設計(OOP)基礎,從OOP概念、類別與物件基本原理,到PHP中類別與物件的應用,並深入探討封裝、繼承等OOP特性,最後以實際練習加強理解。此階段為學生掌握PHP OOP打下堅實基礎。
從基本的OOP概念、PHP基礎回顧,到類別與物件的深入探討、進階概念如繼承、介面與抽象類別,再到實戰應用與設計模式入門,最後以課程總結與未來學習資源提供作結。此課程架構確保學生能夠從基礎到進階,全面掌握PHP物件導向程式設計的核心概念與技術。
本篇文章為Laravel初學者提供了一個指南,深入探討了Laravel的routes目錄下的功能。文章詳細描述了web.php和api.php的差異和使用情境,並簡要介紹了console.php和channels.php的功能。透過這篇文章,讀者可以更好地理解和利用Laravel的路由功能。
Laravel框架中的路由系統是其核心功能之一,它允許開發者輕鬆地定義應用程式的URL結構和相應的邏輯。本篇文章將深入探討Laravel路由的基本概念、進階功能以及實際應用。
在Laravel的MVC架構中,視圖(View)是呈現資料給使用者的關鍵部分。本篇深入探討了視圖的基本概念、建立與管理、與資料的互動方式,以及Blade模板引擎的應用。Blade提供了一套強大的工具,使動態視圖建立更為高效。
本篇深入探討了Model的基本定義、其Controller的關係,以及如何在Controller中使用Model進行CRUD操作。強調了Model的關聯方法,如hasMany,並透過範例程式碼展示了其實際應用。為初學者提供了一個清晰的Laravel入門路徑,同時也為有經驗的開發者提供了實用的參考。
本階段介紹物件導向程式設計(OOP)基礎,從OOP概念、類別與物件基本原理,到PHP中類別與物件的應用,並深入探討封裝、繼承等OOP特性,最後以實際練習加強理解。此階段為學生掌握PHP OOP打下堅實基礎。
從基本的OOP概念、PHP基礎回顧,到類別與物件的深入探討、進階概念如繼承、介面與抽象類別,再到實戰應用與設計模式入門,最後以課程總結與未來學習資源提供作結。此課程架構確保學生能夠從基礎到進階,全面掌握PHP物件導向程式設計的核心概念與技術。
本篇文章為Laravel初學者提供了一個指南,深入探討了Laravel的routes目錄下的功能。文章詳細描述了web.php和api.php的差異和使用情境,並簡要介紹了console.php和channels.php的功能。透過這篇文章,讀者可以更好地理解和利用Laravel的路由功能。
Laravel框架中的路由系統是其核心功能之一,它允許開發者輕鬆地定義應用程式的URL結構和相應的邏輯。本篇文章將深入探討Laravel路由的基本概念、進階功能以及實際應用。
在Laravel的MVC架構中,視圖(View)是呈現資料給使用者的關鍵部分。本篇深入探討了視圖的基本概念、建立與管理、與資料的互動方式,以及Blade模板引擎的應用。Blade提供了一套強大的工具,使動態視圖建立更為高效。
本篇深入探討了Model的基本定義、其Controller的關係,以及如何在Controller中使用Model進行CRUD操作。強調了Model的關聯方法,如hasMany,並透過範例程式碼展示了其實際應用。為初學者提供了一個清晰的Laravel入門路徑,同時也為有經驗的開發者提供了實用的參考。
你可能也想看
Google News 追蹤
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
這一章節旨在介紹 PHP 中的物件導向編程(OOP)概念。通過詳細講解類別、建構子、訪問修飾符(公開、私有、受保護)、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda 表達式、泛型和反射等概念,使讀者能夠理解和應用這些 OOP 技術來編寫更具結構性和可維護性的 PHP 代碼。
Thumbnail
在這一章中,我們探討了 PHP 中的函數,包括函數的基本結構、不同的函數定義方式(如函數聲明、函數表達式、箭頭函數和匿名函數)以及如何呼叫函數。我們還討論了函數的參數處理方式,包括單個參數、多個參數、預設參數值和剩餘參數。此外,我們還介紹了函數的返回值,包括返回單個值、返回物件和返回函數的情況。
Thumbnail
這一章節介紹了PHP的各種資料型別,包括內建型別如整數、浮點數、布爾值、字符串、數組、對象、空值和資源,並解釋了型別轉換的方式。此外,還討論了自訂型別、元組型別、集合型別、陣列型別和字典型別的實現方法。
Thumbnail
在本節中,我們介紹了PHP的基本語法,包括如何在HTML中嵌入PHP代碼,PHP腳本的執行順序,以及多種註解方式。我們還學習了如何定義和使用變數,包括單個變數和多個變數的賦值方法。這些基礎知識將幫助你開始使用PHP進行Web開發。
Thumbnail
這篇文章介紹了面試時以及開始工作後可能會遇到的問題,包括物件導向OOP、SOLID 設計原則、測試方式,以及 Cookie、Session 與 Cache 的相似處與不同處。提供了豐富的相關資訊。
Thumbnail
本章節是一個初級的 TypeScript 教學,主要介紹了 TypeScript 中物件導向程式設計的各種核心概念,包括類別、建構子、存取修飾子、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda 表達式、泛型和反射等。每個概念都通過詳細的解釋和實例代碼來進行深入的介紹。
Thumbnail
本章節旨在介紹JavaScript中的物件導向編程。內容包括類別(Class)的定義和使用,建構子的作用,以及公開,私有,受保護(Protected)等不同訪問修飾符的概念。此外,還涵蓋了繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型、反射等物件導向的主要觀念。
Thumbnail
※ OPP第一大核心-封裝 封裝的精神在於將「方法」、「屬性」和「邏輯」包裝在類別裡面,透過類別的實例來實現。這樣外部物件不需要了解內部的實現細節,只需要知道如何使用該類別提供的接口即可。換句話說,封裝是將內部細節隱藏起來,只暴露必要的部分給使用者。 封裝的核心概念是,使用者如果想要接觸資料,只
Thumbnail
本章節的目的是讓讀者瞭解C#的物件導向特性,包括類別、繼承、多型、封裝等基本概念,以及介面、抽象類別、靜態類別等進階主題。此外,本章節也將介紹如何使用列舉、委派、Lambda表達式、泛型及反射,這些都是C#中常見的強大功能。
Thumbnail
本文介紹了Python中的物件導向程式設計的重要概念,包括類別、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型和反射。每個概念都有對應的程式碼範例來說明其用法和功能。這些概念對於理解和使用Python進行物件導向程式設計至關重要。
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
這一章節旨在介紹 PHP 中的物件導向編程(OOP)概念。通過詳細講解類別、建構子、訪問修飾符(公開、私有、受保護)、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda 表達式、泛型和反射等概念,使讀者能夠理解和應用這些 OOP 技術來編寫更具結構性和可維護性的 PHP 代碼。
Thumbnail
在這一章中,我們探討了 PHP 中的函數,包括函數的基本結構、不同的函數定義方式(如函數聲明、函數表達式、箭頭函數和匿名函數)以及如何呼叫函數。我們還討論了函數的參數處理方式,包括單個參數、多個參數、預設參數值和剩餘參數。此外,我們還介紹了函數的返回值,包括返回單個值、返回物件和返回函數的情況。
Thumbnail
這一章節介紹了PHP的各種資料型別,包括內建型別如整數、浮點數、布爾值、字符串、數組、對象、空值和資源,並解釋了型別轉換的方式。此外,還討論了自訂型別、元組型別、集合型別、陣列型別和字典型別的實現方法。
Thumbnail
在本節中,我們介紹了PHP的基本語法,包括如何在HTML中嵌入PHP代碼,PHP腳本的執行順序,以及多種註解方式。我們還學習了如何定義和使用變數,包括單個變數和多個變數的賦值方法。這些基礎知識將幫助你開始使用PHP進行Web開發。
Thumbnail
這篇文章介紹了面試時以及開始工作後可能會遇到的問題,包括物件導向OOP、SOLID 設計原則、測試方式,以及 Cookie、Session 與 Cache 的相似處與不同處。提供了豐富的相關資訊。
Thumbnail
本章節是一個初級的 TypeScript 教學,主要介紹了 TypeScript 中物件導向程式設計的各種核心概念,包括類別、建構子、存取修飾子、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda 表達式、泛型和反射等。每個概念都通過詳細的解釋和實例代碼來進行深入的介紹。
Thumbnail
本章節旨在介紹JavaScript中的物件導向編程。內容包括類別(Class)的定義和使用,建構子的作用,以及公開,私有,受保護(Protected)等不同訪問修飾符的概念。此外,還涵蓋了繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型、反射等物件導向的主要觀念。
Thumbnail
※ OPP第一大核心-封裝 封裝的精神在於將「方法」、「屬性」和「邏輯」包裝在類別裡面,透過類別的實例來實現。這樣外部物件不需要了解內部的實現細節,只需要知道如何使用該類別提供的接口即可。換句話說,封裝是將內部細節隱藏起來,只暴露必要的部分給使用者。 封裝的核心概念是,使用者如果想要接觸資料,只
Thumbnail
本章節的目的是讓讀者瞭解C#的物件導向特性,包括類別、繼承、多型、封裝等基本概念,以及介面、抽象類別、靜態類別等進階主題。此外,本章節也將介紹如何使用列舉、委派、Lambda表達式、泛型及反射,這些都是C#中常見的強大功能。
Thumbnail
本文介紹了Python中的物件導向程式設計的重要概念,包括類別、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型和反射。每個概念都有對應的程式碼範例來說明其用法和功能。這些概念對於理解和使用Python進行物件導向程式設計至關重要。