成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

用星際爭霸講解PHP面向對象的概念

開發 后端 前端
在學習PHP的時候,感覺自己對面向對象理解還不深刻,很多時候是一頭霧水。通過別人的推薦,找到了這篇通過星際爭霸來講解面向對象概念的文章,轉載出來供有需要的朋友學習。

​在學習PHP的時候,感覺自己對面向對象理解還不深刻,很多時候是一頭霧水。通過別人的推薦,找到了這篇通過星際爭霸來講解面向對象概念的文章,轉載出來供有需要的朋友學習。

一、類和對象

如果玩家制造了一個機槍兵,那么我們怎么表示他呢,因為每個機槍兵有幾個基本的數據要記錄:剩余的血,殺敵數量,攻擊力等等。我們可以用一個數組來記錄一個機槍兵剩余的血和殺敵數量,因為這對于每個機槍兵是獨立的。但攻擊力比較麻煩,因為經過升級,攻擊力會增加,這就必須要找出所有表示機槍兵的數組,然后進行修改,非常麻煩。從這里我們可以看出一件事情,首先每個機槍兵有獨立的數據需要記錄和修改,比如剩余的血。同時他們有相同的數據需要共用,比如攻擊力。這時候面向對象就能幫上我們的忙了。

1.1、類的定義

我們先來處理一部分問題,也就是每個機槍兵獨有的數據。

  1. class marine 
  2.    public $blood = 50; //剩余的血 
  3.    public $kills = 0; //殺敵數量 
  4.    //這個函數(通常叫做方法)表示攻擊敵人時候的運行代碼    function attack($enemy) 
  5.    { 
  6.    //攻擊敵人的代碼 
  7.    } 

這叫做類,我們建立了一個表示所有機槍兵的類marine,這里面保留了需要每個兵獨有的數據,比如上面代碼里的剩余的血。

1.2、對象的創建和使用

接下來我們來使用對象,也就是每個機槍兵:

  1. $m1 = new marine(); 

通過new后面加一個類的名字和括號,我們新建了一個機槍兵$m1,$m1被叫做類marine的對象,我們可以把它想象成一個特殊變量,只不過里面保存了多個數據。如果需要使用或者操作某個機槍兵的血(對象的屬性),只要用$m1->blood來表示就可以了:

  1. echo $m1->blood;//輸出機槍兵$m1剩余的血 

我們再建立一個機槍兵

  1. $m2 = new marine(); 

如果此時$m1被敵人攻擊過了,還剩下10個血。而$m2沒受過攻擊:

  1. echo $m1->blood;//結果是10 
  2. echo $m2->blood;//結果是50 

使用對象可以很簡單的保存每個機槍兵的血,不會互相影響。如果機槍兵$m1攻擊敵人的時候,可以這樣使用對象的方法:

  1. $m1->attack($z1);//假設攻擊的是某個小狗的對象$z1 

不同的類內可以用同名的函數,比如小狗的類Zergling里面也可以有一個函數attack。要注意的是,從PHP5開始,無論在哪里改變一個對象的屬性,都能改變它。比如上面一個小狗對象被作為參數傳入機槍兵的attack函數,執行函數之后這個小狗對象的血減少了,這和一般的函數不同。但這是很直觀的,如果一個小狗被攻擊了,它的血就應該減少。

二、構造函數和析構函數

每次我們新建一個機槍兵的時候,總人口應該加1,如果一個機槍兵被殺,人口應該減少1。可以通過構造函數和析構函數來自動處理:

  1. class marine 
  2.    //構造函數 
  3.    function __construct() 
  4.    { 
  5.    //增加總人口的代碼 
  6.    } 
  7.    //析構函數 
  8.    function __destruct() 
  9.    { 
  10.    //減少總人口的代碼 
  11.    } 

在一個類中,名字為__construct的函數叫做構造函數,每次new新建一個類的對象的時候就會執行:

  1. $m1 = new marine();//每次制造一個機槍兵時系統會調用類marine的構造函數,自動增加總人口 

在一個類中,名字為__destruct的函數叫做析構函數,每次銷毀一個類的對象的時候就會執行:

  1. unset($m1);//unset可以用于對象,表示銷毀一個對象。每次一個機槍兵被殺時系統會調用類marine的析構函數,自動減少總人口 

三、靜態

機槍兵的攻擊力是屬于所有機槍兵對象,每個機槍兵的攻擊力都是一樣的,如果升級,應該一起變化。這就用到static,表示靜態:

  1. class marine 
  2.    static $attackNumber = 10; //攻擊力的數字 
  3.    //這個函數表示攻擊敵人時候的運行代碼    function attack($enemy) 
  4.    { 
  5.    //攻擊敵人的代碼,$enemy->blood表示敵人對象的血屬性 
  6.    $enemy->blood -= self::$attackNumber
  7.    } 

靜態屬性表示類所有的對象都共享的屬性,一旦改變,所有的對象都跟著變化。靜態屬性用static開頭,比如上面的static $attackNumber。靜態屬性可以用類直接訪問:

  1. echo marine::$attackNumber;//顯示10 

如果類以內的函數訪問,用self::$attackNumber表示本類的$attackNumber屬性。所以如果我們升級了機槍兵的攻擊力,所有的 機槍兵都受影響,這就是面向對象的好處之一,也解決了我們前面討論的共同數據的問題。函數也可以是靜態的,這樣就可以用類直接訪問,不需要新建對象來調 用:

  1. class marine 
  2.    static $attackNumber = 10; //攻擊力的數字 
  3.    //這個函數表示機槍兵升級的運行代碼    static  function upgrade() 
  4.    { 
  5.    self::$attacknum++; 
  6.    } 

#p#

如果科技建筑升級完畢,直接就調用這個函數:

marine::upgrade();
  1. //建筑類 
  2. class building 
  3.    function fly() 
  4.    { 
  5.    //建筑飛行的代碼 
  6.    } 
  7. //兵營類 
  8. class marineBuilding extends building 
  9.    function createMarine() 
  10.    { 
  11.    //制造機槍兵的代碼 
  12.    } 
  13. //坦克房類 
  14. class tankBuilding extends building 
  15.    function createTank() 
  16.    { 
  17.    //制造坦克的代碼 
  18.    } 
  19.  
  20. 接下來,我們看看繼承產生的效果: 
  21. //如果造了一個兵營: 
  22. $mb1 = new marineBuilding(); 
  23. /** 
  24. 一旦他需要飛行,就可以直接使用建筑類的函數fly(),盡管兵營類的定義里沒有這個函數 
  25. */ 
  26. $mb1->fly(); 
  27. //而他要制造機槍兵的時候: 
  28. $mb1->createMarine(); 

同樣是繼承建筑類的坦克房類,就無法制造機槍兵,因為這是兵營類的個性。如果在子類中的函數調用父類的函數,要使用parent,比如parent::fly()。注意,一個類只能有一個父類,PHP不允許多重繼承,也就是說一個孩子只能有一個爹,一個爹可以有N個孩子!

五、訪問控制

如果用$attackNumber = 10表示屬性的話,系統默認是public $attackNumber = 10,所以建議這樣寫:

  1. class marine 
  2. public static $attackNumber = 10; //攻擊力的數字 

public表示這個屬性是公共的,也就是在任何地方都可以訪問和操作的。但這就存在一些問題,如果有玩家知道了類marine的一些代碼結構,那他做個簡單的補丁程序,運行的時候加載上去:

  1. //補丁 
  2. marine::$attackNumber = 10000; 

這樣的話,他的機槍兵有10000的攻擊力,呵呵,這樣的話,誰打得過他!為此我們要用private,表示這個屬性只有類里面的函數才能訪問:

  1. class marine 
  2.     private static $attackNumber = 10//攻擊力的數字 
  3.    //這個函數表示機槍兵升級的運行代碼    function upgrade() 
  4.    { 
  5.       //這樣防止無限升級 
  6.       if(self::$attacknum<13
  7.       { 
  8.       self::$attacknum++; 
  9.       } 
  10.    } 

這樣一來,只有升級才能改變機槍兵的攻擊力。但是現在往往是團隊開發,而且很多用到類的繼承,如果private的話,子類就無法訪問了,但又不希望隨便都可以修改某些屬性。那么可以用protected,protected的屬性可以被子類的函數訪問。

六、重載

6.1、屬性重載

如果我們把地面部隊作為一個類,讓機槍兵類來繼承他,這時候如果地面部隊類和機槍兵類里面都定義了攻擊力$attackNumber,那么每個兵的攻擊力就決定于機槍兵類,而不是地面部隊。這就叫做重載。

  1. //地面部隊 
  2. class groundArmy 
  3. public $attackNumber = 5; 
  4. //機槍兵 
  5. class marine extends groundArmy 
  6. public $attackNumber = 10; //攻擊力的數字 
  7. $m1 = new marine();//新建一個機槍兵 
  8. echo $m1->attackNumber;//顯示攻擊力為10 

6.2、函數重載

重載也可以用于函數,子類的函數如果和父類函數同名,除非另行說明,否則子類的對象默認調用子類內的函數。比如人族的鬼兵類ghost和神族類的黑 暗圣堂類(隱刀),都是隱形兵種,但是鬼兵隱形的時候會減少能量,黑暗圣堂根本沒有能量屬性。如果我們把隱形能力作為父類,鬼兵類ghost和神族類的黑 暗圣堂類DarkTemplar來繼承它,同時實現不同的隱形代碼:

#p#

  1. //隱形能力類 
  2. class concealAbility 
  3.    //這個函數表示隱形的運行代碼    function conceal() 
  4.    { 
  5.       //隱形的運行代碼 
  6.    } 
  7. //鬼兵類 
  8. class ghost extends concealAbility 
  9. $energy = 150; 
  10.    //這個函數表示隱形的運行代碼    function conceal() 
  11.    { 
  12.       //隱形的運行代碼 
  13.       //減少鬼兵的能量,$this表示當前對象,也就是當前這個鬼兵 
  14.       $this->energy -= 25; 
  15.    } 
  16. //黑暗圣堂類 
  17. class DarkTemplar extends concealAbility 
  18.    //這個函數表示隱形的運行代碼    function conceal() 
  19.    { 
  20.       //隱形的運行代碼,不影響能量 
  21.    } 
  22. //新建一個鬼兵 
  23. $g1 = new ghost(); 
  24. //顯示能量為150 
  25. echo $g1->energy; 
  26. //鬼兵隱形 
  27. $g1->conceal(); 
  28. //顯示能量為125 
  29. echo $g1->energy; 
  30. //新建一個黑暗圣堂 
  31. $d1 = new DarkTemplar(); 
  32. //黑暗圣堂隱形,他沒有能量屬性 
  33. $g1->conceal(); 

七、接口

PHP不允許多重繼承,那么有些問題就難辦了。假如為了規范處理,我們把隱形的能力建立一個類,然后把飛行能力放一個類,那么人族的偵察機怎么處 理?不能繼承兩個類!那我們不用繼承也行,但是開發組的其他人一旦涉及到偵察機,要把長長的代碼讀一遍嗎?有沒有可能知道類的所有方法的簡要描述?可以用 到接口interface,一個類可以執行(繼承)多個接口,接口中定義的函數不能有函數體,執行接口的類必須將這些函數完整定義。這樣我們知道偵察機實現了飛行能力接口,必然有接口里面描述的飛行方法:

  1. //隱形能力的接口 
  2. interface concealAbility 
  3. public function conceal(); 
  4. //飛行能力的接口 
  5. interface flyAbility 
  6. public function fly(); 
  7. //偵察機類 
  8. class Wraith implements flyAbility, concealAbility 
  9.    //這個函數表示偵察機飛行的運行代碼    function fly() 
  10.    { 
  11.       //飛行的運行代碼 
  12.    } 
  13.    //這個函數表示偵察機隱形的運行代碼    function conceal() 
  14.    { 
  15.       //隱形的運行代碼 
  16.    } 

八、總結

我們討論了PHP面向對象的基本知識,通過星際爭霸這一經典的游戲來說明,大家可以看到面向對象的初步作用。我們看到通過面向對象可以使代碼更加清晰,類將代碼組織起來,比較方便的重復使用。同時對象也減少了變量的沖突,方便相關性數據的保存和使用。如果要解決的問題涉及很多方面,面向對象可以演化出更加靈活和有技巧的方式,比如通常提到的設計模式,和很多框架。當然,面向對象也有缺點,從上面的代碼可以看到,首先代碼就多了,簡單的任務如果定義許多類,反而麻煩。對于簡單任務,面向對象也可能使代碼運行的效率降低。

原文鏈接:http://www.biaodianfu.com/starcraft-object-oriented.html

責任編輯:陳四芳 來源: biaodianfu.com
相關推薦

2012-01-17 12:39:09

JavaSwing

2010-07-19 13:15:49

星際爭霸2

2010-01-14 17:17:32

云計算

2014-03-18 15:23:58

星際爭霸ARM平臺

2011-05-13 11:49:42

網絡安全技術周刊

2019-01-25 18:37:20

AI數據科技

2009-11-23 19:24:01

PHP面向對象編程

2023-11-18 09:48:23

2009-08-18 09:47:44

百強游戲任天堂

2021-12-01 10:01:52

AI 游戲人工智能

2010-01-18 16:57:09

云計算星際爭霸

2019-08-12 08:43:53

GitHub代碼開發者

2010-08-01 22:30:12

2024-09-23 15:04:16

2022-06-02 15:19:31

架構智能強化學習

2009-07-24 08:17:37

巫妖王之怒亮相Chin魔獸世界

2019-01-30 11:17:46

2010-08-03 09:43:59

IT技術周刊

2009-10-13 14:19:03

VB.NET面向對象編

2011-04-19 18:17:36

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品高潮呻吟久久aⅴ码 | 精品亚洲一区二区三区 | 夜夜摸天天操 | 国产欧美精品一区二区 | 国产99久久 | 免费骚视频 | 国产精品麻 | 精品久| 亚洲欧洲色视频 | 欧美一区二区在线免费观看 | 精品国产欧美一区二区三区不卡 | 美女逼网站 | 国产91一区 | 91tv在线观看 | 97超碰站 | 欧美精品一区在线发布 | 美女午夜影院 | 国产精品18久久久久久白浆动漫 | 欧美日韩亚洲系列 | 国产日韩精品一区二区 | www.色婷婷| 国产精品夜夜春夜夜爽久久电影 | 成人精品鲁一区一区二区 | 欧美美女爱爱 | 久久久久久久久久爱 | 国产精品7777777| 91美女在线观看 | 国产9999精品 | 性做久久久久久免费观看欧美 | 中文日韩在线 | 成人教育av | 黄色一级大片在线免费看产 | 成人av播放 | 91精品国产91久久久久久不卞 | av在线免费观看网站 | 亚洲视频免费观看 | a国产视频 | 日韩视频国产 | 欧美日韩在线一区二区三区 | 日韩av成人 | 成人1区 |