Eric Tu
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
      • Invitee
    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Versions and GitHub Sync Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
Invitee
Publish Note

Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

Your note will be visible on your profile and discoverable by anyone.
Your note is now live.
This note is visible on your profile and discoverable online.
Everyone on the web can find and read all notes of this public team.
See published notes
Unpublish note
Please check the box to agree to the Community Guidelines.
View profile
Engagement control
Commenting
Permission
Disabled Forbidden Owners Signed-in users Everyone
Enable
Permission
  • Forbidden
  • Owners
  • Signed-in users
  • Everyone
Suggest edit
Permission
Disabled Forbidden Owners Signed-in users Everyone
Enable
Permission
  • Forbidden
  • Owners
  • Signed-in users
Emoji Reply
Enable
Import from Dropbox Google Drive Gist Clipboard
   owned this note    owned this note      
Published Linked with GitHub
Subscribed
  • Any changes
    Be notified of any changes
  • Mention me
    Be notified of mention me
  • Unsubscribe
Subscribe
物件導向基礎 === ###### tags: `DesignPatterns` ## Object-Oriented Programming 什麼是物件導向? 根據 [WIKI](https://zh.wikipedia.org/wiki/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1) 中的定義如下 : 物件導向程式設計(英語:Object-oriented programming,縮寫:OOP)是種具有物件概念的程式程式設計典範,同時也是一種程式開發的抽象方針。它可能包含資料、屬性、程式碼與方法。物件則指的是類別的實例。它將物件作為程式的基本單元,將程式和資料封裝其中,以提高軟體的重用性、靈活性和擴充性,物件裡的程式可以存取及經常修改物件相關連的資料。在物件導向程式程式設計裡,電腦程式會被設計成彼此相關的物件。 りしりこんさ小 ??? 簡單的來說,物件導向設計可以視為一種思考方式,將所有問題做抽象化思考。 將每件事情分解成物件,每個物件又有各自的行為和狀態。透過這些狀態間的訊息傳遞,互相依賴,來達成設計上的需求,比起傳統的程序導向思考,物件導向這種抽象化思考更能夠便於管理物件以及開發解決問題。 ### 大綱 - 類別 (Class) 與 物件 (Object) - 類別描述物件而物件則是類別的實例。建立物件的動作稱為「實例化」。 以藍圖作比喻,若類別是藍圖,物件就是根據藍圖所蓋的建築物。 - 封裝(Encapsulation): - 將物件內部的資訊隱藏起來,限制外部的直接存取,並提供一組或多組介面提供外部存取。 - [抽象資料型態 (abstract data types)](https://zh.wikipedia.org/wiki/%E6%8A%BD%E8%B1%A1%E8%B3%87%E6%96%99%E5%9E%8B%E5%88%A5): - 在電腦科學中,抽象資料型態代表的是某種特定的資料結構或者數學模型,例如,抽象的堆疊(stack)由3個操作定義:推入 push,彈出 pop,檢視堆疊頂端資料 peek。 - 狀態(State)的保存 : - 物件狀態的處理 - 物件特性 : - 物件本身的屬性? - 訊息(Messages) : - 物件與物件之間透過訊息傳遞彼此協作。 - 繼承(Inheritance) - 又稱為一般化(Generalization)與特殊化(Specialization)的關係,A繼承B乃指物件類別A是物件類別B的一種,因此物件類別A可以繼承物件類別B的屬性與方法。兩個以上類別一般化後之類別稱為超類別(Superclass)。 - 多型(Polymorphism) : - 一個訊息的意義是由接收者決定而不是發送者,例如發動引擎對汽車跟飛機來說實現的方式就不一樣。 - 一般化(Generality) : - 一般化指的是將共通特性從兩個或以上的類別中提取出來並定義一個擁有這些特性的超類別的過程,其中共通的特性可以是屬性、關係、方法等。 ### 類別與實體 物件是一個獨立自主的實體,用一組可識別的特性和行為來表示。 貓叫 ```php function moew() { echo 'moew'; } moew(); ``` 其他地方也可能用到貓叫這個功能 ``` function shout() { moew(); } shout(); ``` 貓叫這個 function 應該是屬於貓的 ``` class Cat { public function shout() { echo 'moew'; } } ``` **類別就是具有相同之屬性和功能的物件的抽象集合** Class 表示定義類別的關鍵字 Cat 就是類別的名稱 Shout 就是類別的方法 對外公開的方法使用 public 屬性修飾 今天要使用貓這個類別的時候,只要將類別實體化就可以了 什麼叫做實體化? 實體,就是一個真實的物件,例如 我 就是 人 這個類別的實體, 而使實體化就是建立物件的過程,使用 new 關鍵字來建立。 ```php // 定義類別 class Cat { public function shout() { echo 'moew'; } } // 實體化 $cat = new Cat(); // 呼叫類別方法 $cat->shout(); ``` ### 建構式 建構式,又叫建構函式,其實就是對類別進行初始化。建構式與類別同名,無返回值,在 new 時調用。 所有的類別都有建構式,如果你沒有做任何定義,系統會自動產生空的建構式,若你有定義的建構式,那麼預定地建構式就會生效了。 ```php <?php class Cat { private $name = ''; function __construct($name = '') { $this->name = $name; } public function moew() { echo $this->name . ' moew'; } } $cat = new Cat('nyan cat'); $cat->moew(); // output : nyan cat moew ``` ### 屬性與修飾子 屬性是一個方法或一對方法,但在調用它的程式碼看來,它是一個欄位,即屬性適合於以欄位的方式使用方法調用的場合。 欄位式儲存類別要滿足其設計所需要的資料,欄位是與類別相關的變數。 例如: ``` private $name = 'nyan'; ``` #### const 常數 不變的量可以用常數宣告,在定義和使用常數的時候不需要使用 $ 宣告。(介面中也可以定義常數) ``` class MyClass { const CONST_VALUE = 'A constant value'; } echo MyClass::CONST_VALUE; // A constant value ``` #### static 變數 使用時不用建立物件就可以用 ``` ClassName::$staticVariable ``` #### public 變數 要建立物件後才可以用,但可以在類別以外的地方使用 ``` $test = new Test(); $test->pubilcVariable; ``` #### protected 變數 必須建立物件後才可以用,不可以在類別以外的地方做使用,但可以被子類別使用。 #### private 變數 必須建立物件後才能使用,只能在類別內使用且不能被繼承。 ```php= <?php class MyClass { const CONST_VALUE = 'A constant value'; } $classname = 'MyClass'; echo $classname::CONST_VALUE; // As of PHP 5.3.0 echo "\n"; echo MyClass::CONST_VALUE; echo "\n"; class OtherClass extends MyClass { public static $my_static = 'static var'; public static function doubleColon() { echo parent::CONST_VALUE . "\n"; echo self::$my_static . "\n"; } } $classname = 'OtherClass'; $classname::doubleColon(); // As of PHP 5.3.0 OtherClass::doubleColon(); /* A constant value A constant value A constant value static var A constant value static var */ ``` ```php= <?php class Test { const CONST_VALUE = 'CONST VALUE'; static $staticValue = 'staticValue'; public $publicValue = 'publicValue'; private $privateValue = 'privateValue'; protected $protectedValue = 'portectedValue'; } echo Test::CONST_VALUE; // const 常數不需要建立物件也不需要$字號就可以直接使用 echo "\n"; echo Test::$staticValue; // static 不需要建立物件就可以直接使用 echo "\n"; $test = new Test(); echo $test->publicValue; // public 建立物件後可以讓外部調用 echo "\n"; class Test2 extends Test { function testExtendGetPublic() { echo $this->pubilcValue; } function testExtendGetProtected() { echo $this->protectedValue; } function testExtendGetPrivate() { echo $this->privateValue; } } $test2 = new Test2(); $test2->testExtendGetPublic(); // Undefined property echo "\n"; $test2->testExtendGetProtected(); echo "\n"; $test2->testExtendGetPrivate(); // Undefined property echo "\n"; /* CONST VALUE staticValue publicValue <br /> <b>Notice</b>: Undefined property: Test2::$pubilcValue in <b>[...][...]</b> on line <b>29</b><br /> portectedValue <br /> <b>Notice</b>: Undefined property: Test2::$privateValue in <b>[...][...]</b> on line <b>37</b><br /> */ ``` ### 封裝 每個物件都包含它進行操作所需要的所有資訊,這個特性稱為封裝,因此物件不必依賴其他物件來完成自己的操作。 封裝的好處: - 良好的封裝能夠減少耦合 - 類別內部的實現可以自由地更改 - 類別具有清晰的對外界介面 ### 繼承 物件的繼承代表了一種 is-a 的關係,如果兩個物件 A 和 B,可以描述為 B 是 A,則表明 B 可以繼承 A。 例如: 貓是哺乳動物。 繼承者還可以理解為是對被繼承者的特殊化,因為他除了具備了被繼承者的特性外,還具備自己獨有的個性。 繼承定義了類別如何互相關聯,共用特性。繼承的工作方式是,定義父類別和子類別,或叫做基礎類別和衍生類別,其中子類別繼承父類別的所有特性。子類別不但繼承了父類別的所有特性,還可以定義新的特性。 繼承的幾個特性: 1. 子類別擁有父類別非 private 的屬性和功能。 2. 子類別具有自己的數性和功能,即子類別可以擴展父類別沒有的屬性和功能 3. 子類別可以用自己的方法實現父類別的功能。 對於建構式繼承的問題,在 PHP 之中說明如下 https://www.php.net/manual/en/language.oop5.decon.php **Note: Parent constructors are not called implicitly if the child class defines a constructor. In order to run a parent constructor, a call to parent::__construct() within the child constructor is required. If the child does not define a constructor then it may be inherited from the parent class just like a normal class method (if it was not declared as private).** ``` <?php class BaseClass { function __construct() { print "In BaseClass constructor\n"; } } class SubClass extends BaseClass { function __construct() { parent::__construct(); print "In SubClass constructor\n"; } } class OtherSubClass extends BaseClass { // inherits BaseClass's constructor } // In BaseClass constructor $obj = new BaseClass(); // In BaseClass constructor // In SubClass constructor $obj = new SubClass(); // In BaseClass constructor $obj = new OtherSubClass(); ?> ``` 繼承的缺點: 1. 當使用繼承時,父類別變動,子類別也不得不變 2. 繼承會破壞封裝,父類別實現細節暴露給子類別,增加了類別間的耦合 當兩個類別之間具備了 is-a 的關係時,就可以考慮使用繼承。 ### 多型 多型表示不同的物件可以執行相同的動作,但要透過他們自己的實現程式碼來執行 工廠方法中每個工廠都各自實作相同的方法, 在客戶端中實際上客戶只要知道他調用了工廠方法,但由哪個工廠內部如何實做方法以及執行細節都不需知道。 ```php <?php interface ShapesInterface{ public function getArea(); } class Rectangle implements ShapesInterface{ public function getArea(){ return "Rectangle Area"; } } class Polygon implements ShapesInterface{ public function getArea(){ return "Polygon Area"; } } class SimpleShapeFactory { public function createShape($shape = 'Rectangle') { return new $shape(); } } $shapeFactory = new SimpleShapeFactory(); $shape = $shapeFactory->createShape('Rectangle'); $area = $shape->getArea(); // "Rectangle Area" ``` ### 抽象類別 1. 抽象類別不能實體化 2. 抽象方法是必須被子類別重寫的方法 3. 如果類別中包含抽象方法,那麼類別就必須定義為抽象類別,不論是否還包含其他一班方法。 抽象類別擁有盡可能多的共同程式碼,擁有盡可能少的資料。 抽象類別通常代表一個抽象概念,它提供一個繼承的出發點,當設計一個新的抽象雷別實,一定是用來繼承的,所以,在一個以繼承關係形成的等級結構裡面,樹葉節點應當是具體類別,而樹枝節點均應當是抽象類別。 ### 介面 介面是把隱式公共方法和屬性組合起來,以封裝特定功能的一個集合。一旦類別實現了介面,類別就可以支援介面所指定的所有屬性和成員。宣告介面在語法上與宣告抽象類別完全相同,但不允許提供介面中任何成員的執行方式。 介面不能實體化,不能有建構式、欄位,不能有修飾子 實現介面的類別必須要實現介面中的所有方法和屬性。 一個類別可以支援多個介面 ### 抽象類別 & 介面 型態上來說: 1. 抽象類別可以給出一些成員的實現,介面卻不包含成員的實現 2. 抽象類別的抽象成員可以被子類別部分實現,介面的成員需要實現類別完全實現。 3. 一個類別只能繼承一個抽象類別,一個類別可以實現多個介面。 意義上來說: 1. 類別是對物件的抽象; 抽象類別是對類別的抽象(對類別整體例如欄位、屬性、方法進行抽象); 介面是對行為的抽象(對類別的局部行為)。 2. 如果行為跨越不同類別的物件,可使用介面;對於一些像似的類別物件,用繼承抽象類別。(實現界面和繼承抽象並不衝突,超人可以繼承人類再實現飛行介面) 3. 從設計角度來說,抽象類別是從子類別中發現了公共的東西,泛化出父類別,然後子類別繼承父類別,而介面是根本不知子類別的存在,方法如何實現還不確認,預先定義。 4. 抽象類別是自底而上抽象出來的(往往透過重構時發現),而介面則是自頂向下設計出來的。 --- https://code.tutsplus.com/tutorials/understanding-and-applying-polymorphism-in-php--net-14362 https://newaurora.pixnet.net/blog/post/190301967-static%E8%AE%8A%E6%95%B8%E3%80%81public%E8%AE%8A%E6%95%B8%E3%80%81private%E8%AE%8A%E6%95%B8%E3%80%81protected%E8%AE%8A https://www.php.net/manual/en/language.types.callable.php http://yes.nctu.edu.tw/vc/ref/oop/oop.pdf [搞笑談軟工 - 什麼是物件導向(2):Object, Class, Instance](http://teddy-chen-tw.blogspot.com/2012/01/2object-class-instance.html) [很棒的舉例](https://medium.com/@totoroLiu/%E7%89%A9%E4%BB%B6%E5%B0%8E%E5%90%91-object-oriented-programming-%E6%A6%82%E5%BF%B5-5f205d437fd6) https://sourcemaking.com/uml/modeling-it-systems/structural-view/generalization-specialization-and-inheritance

Import from clipboard

Paste your markdown or webpage here...

Advanced permission required

Your current role can only read. Ask the system administrator to acquire write and comment permission.

This team is disabled

Sorry, this team is disabled. You can't edit this note.

This note is locked

Sorry, only owner can edit this note.

Reach the limit

Sorry, you've reached the max length this note can be.
Please reduce the content or divide it to more notes, thank you!

Import from Gist

Import from Snippet

or

Export to Snippet

Are you sure?

Do you really want to delete this note?
All users will lose their connection.

Create a note from template

Create a note from template

Oops...
This template has been removed or transferred.
Upgrade
All
  • All
  • Team
No template.

Create a template

Upgrade

Delete template

Do you really want to delete this template?
Turn this template into a regular note and keep its content, versions, and comments.

This page need refresh

You have an incompatible client version.
Refresh to update.
New version available!
See releases notes here
Refresh to enjoy new features.
Your user state has changed.
Refresh to load new user state.

Sign in

Forgot password

or

By clicking below, you agree to our terms of service.

Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
Wallet ( )
Connect another wallet

New to HackMD? Sign up

Help

  • English
  • 中文
  • Français
  • Deutsch
  • 日本語
  • Español
  • Català
  • Ελληνικά
  • Português
  • italiano
  • Türkçe
  • Русский
  • Nederlands
  • hrvatski jezik
  • język polski
  • Українська
  • हिन्दी
  • svenska
  • Esperanto
  • dansk

Documents

Help & Tutorial

How to use Book mode

Slide Example

API Docs

Edit in VSCode

Install browser extension

Contacts

Feedback

Discord

Send us email

Resources

Releases

Pricing

Blog

Policy

Terms

Privacy

Cheatsheet

Syntax Example Reference
# Header Header 基本排版
- Unordered List
  • Unordered List
1. Ordered List
  1. Ordered List
- [ ] Todo List
  • Todo List
> Blockquote
Blockquote
**Bold font** Bold font
*Italics font* Italics font
~~Strikethrough~~ Strikethrough
19^th^ 19th
H~2~O H2O
++Inserted text++ Inserted text
==Marked text== Marked text
[link text](https:// "title") Link
![image alt](https:// "title") Image
`Code` Code 在筆記中貼入程式碼
```javascript
var i = 0;
```
var i = 0;
:smile: :smile: Emoji list
{%youtube youtube_id %} Externals
$L^aT_eX$ LaTeX
:::info
This is a alert area.
:::

This is a alert area.

Versions and GitHub Sync
Get Full History Access

  • Edit version name
  • Delete

revision author avatar     named on  

More Less

Note content is identical to the latest version.
Compare
    Choose a version
    No search result
    Version not found
Sign in to link this note to GitHub
Learn more
This note is not linked with GitHub
 

Feedback

Submission failed, please try again

Thanks for your support.

On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

Please give us some advice and help us improve HackMD.

 

Thanks for your feedback

Remove version name

Do you want to remove this version name and description?

Transfer ownership

Transfer to
    Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

      Link with GitHub

      Please authorize HackMD on GitHub
      • Please sign in to GitHub and install the HackMD app on your GitHub repo.
      • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
      Learn more  Sign in to GitHub

      Push the note to GitHub Push to GitHub Pull a file from GitHub

        Authorize again
       

      Choose which file to push to

      Select repo
      Refresh Authorize more repos
      Select branch
      Select file
      Select branch
      Choose version(s) to push
      • Save a new version and push
      • Choose from existing versions
      Include title and tags
      Available push count

      Pull from GitHub

       
      File from GitHub
      File from HackMD

      GitHub Link Settings

      File linked

      Linked by
      File path
      Last synced branch
      Available push count

      Danger Zone

      Unlink
      You will no longer receive notification when GitHub file changes after unlink.

      Syncing

      Push failed

      Push successfully