欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

php面向?qū)ο蠡A(chǔ)詳解【星際爭(zhēng)霸游戲案例】

 更新時(shí)間:2020年01月23日 11:18:16   作者:DavidHHuan  
這篇文章主要介紹了php面向?qū)ο蠡A(chǔ),結(jié)合星際爭(zhēng)霸游戲案例詳細(xì)分析了PHP面向?qū)ο箢悺⒗^承、重載、接口等相關(guān)概念與使用技巧,需要的朋友可以參考下

本文實(shí)例講述了php面向?qū)ο蠡A(chǔ)。分享給大家供大家參考,具體如下:

前言

面向?qū)ο蟛┐缶?,?duì)于從未接觸過得的人,會(huì)覺得一頭霧水。
學(xué)習(xí)的資料很多,但大多比較抽象,所以我用經(jīng)典的游戲-星際爭(zhēng)霸來討論P(yáng)HP面向?qū)ο蟆?br /> 現(xiàn)在假設(shè)我們來用PHP開發(fā)星際爭(zhēng)霸,從而接觸PHP面向?qū)ο蟆?br /> 注意,為了便于學(xué)習(xí),除了特殊說明,否則各部分代碼之間沒有關(guān)聯(lián)。而且同一件事情往往用的是不同的代碼。
另外我也不去考證各個(gè)兵種的屬性數(shù)字,僅僅用來說明。

一、類和對(duì)象

如果玩家制造了一個(gè)機(jī)槍兵,那么我們?cè)趺幢硎舅?,因?yàn)槊總€(gè)機(jī)槍兵有幾個(gè)基本的數(shù)據(jù)要記錄:剩余的血,殺敵數(shù)量,攻擊力等等。
我們可以用一個(gè)數(shù)組來記錄一個(gè)機(jī)槍兵剩余的血和殺敵數(shù)量,因?yàn)檫@對(duì)于每個(gè)機(jī)槍兵是獨(dú)立的。
但攻擊力比較麻煩,因?yàn)榻?jīng)過升級(jí),攻擊力會(huì)增加,這就必須要找出所有表示機(jī)槍兵的數(shù)組,然后進(jìn)行修改,非常麻煩。
從這里我們可以看出一件事情,首先每個(gè)機(jī)槍兵有獨(dú)立的數(shù)據(jù)需要記錄和修改,比如剩余的血。同時(shí)他們有相同的數(shù)據(jù)需要共用,比如攻擊力。
這時(shí)候面向?qū)ο缶湍軒蜕衔覀兊拿α恕?/p>

1.1、類的定義

我們先來處理一部分問題,也就是每個(gè)機(jī)槍兵獨(dú)有的數(shù)據(jù)。

<?php 
  class marine
  {
    public $blood = 50; //剩余的血
    public $kills = 0; //殺敵數(shù)量
    //這個(gè)函數(shù)(通常叫做方法)表示攻擊敵人時(shí)候的運(yùn)行代碼
    function attack($enemy)
    {
      //攻擊敵人的代碼
    }
  }
?>

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

1.2、對(duì)象的創(chuàng)建和使用

接下來我們來使用對(duì)象,也就是每個(gè)機(jī)槍兵:

<?php
  $m1 = new marine();
?>

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

我們?cè)俳⒁粋€(gè)機(jī)槍兵

<?php 
  $m2 = new marine();
?>

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

<?php
  echo $m1->blood;//結(jié)果是10
  echo $m2->blood;//結(jié)果是50
?>

使用對(duì)象可以很簡(jiǎn)單的保存每個(gè)機(jī)槍兵的血,不會(huì)互相影響。
如果機(jī)槍兵$m1攻擊敵人的時(shí)候,可以這樣使用對(duì)象的方法:

<?php
  $m1->attack($z1);//假設(shè)攻擊的是某個(gè)小狗的對(duì)象$z1
?>

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

二、構(gòu)造函數(shù)和析構(gòu)函數(shù)

每次我們新建一個(gè)機(jī)槍兵的時(shí)候,總?cè)丝趹?yīng)該加1,如果一個(gè)機(jī)槍兵被殺,人口應(yīng)該減少1。
可以通過構(gòu)造函數(shù)和析構(gòu)函數(shù)來自動(dòng)處理:

<?php
  class marine
  {
    //構(gòu)造函數(shù)
    function __construct()
    {
      //增加總?cè)丝诘拇a
    }
    //析構(gòu)函數(shù)
    function __destruct()
    {
      //減少總?cè)丝诘拇a
    }
  }
?>

在一個(gè)類中,名字為__construct的函數(shù)叫做構(gòu)造函數(shù),每次new新建一個(gè)類的對(duì)象的時(shí)候就會(huì)執(zhí)行:

<?php
  $m1 = new marine();//每次制造一個(gè)機(jī)槍兵時(shí)系統(tǒng)會(huì)調(diào)用類marine的構(gòu)造函數(shù),自動(dòng)增加總?cè)丝?
?>

在一個(gè)類中,名字為__destruct的函數(shù)叫做析構(gòu)函數(shù),每次銷毀一個(gè)類的對(duì)象的時(shí)候就會(huì)執(zhí)行:

<?php
  unset($m1);//unset可以用于對(duì)象,表示銷毀一個(gè)對(duì)象。每次一個(gè)機(jī)槍兵被殺時(shí)系統(tǒng)會(huì)調(diào)用類marine的析構(gòu)函數(shù),自動(dòng)減少總?cè)丝?
?>

三、靜態(tài)

機(jī)槍兵的攻擊力是屬于所有機(jī)槍兵對(duì)象,每個(gè)機(jī)槍兵的攻擊力都是一樣的,如果升級(jí),應(yīng)該一起變化。
這就用到static,表示靜態(tài):

<?php
  class marine
  {
    static $attackNumber = 10; //攻擊力的數(shù)字
    //這個(gè)函數(shù)表示攻擊敵人時(shí)候的運(yùn)行代碼
    function attack($enemy)
    {
      //攻擊敵人的代碼,$enemy->blood表示敵人對(duì)象的血屬性
      $enemy->blood -= self::$attackNumber;
    }
  }
?>

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

<?php
  echo marine::$attackNumber;//顯示10
?>

如果類以內(nèi)的函數(shù)訪問,用self::$attackNumber表示本類的$attackNumber屬性
所以如果我們升級(jí)了機(jī)槍兵的攻擊力,所有的機(jī)槍兵都受影響,這就是面向?qū)ο蟮暮锰幹?,也解決了我們前面討論的共同數(shù)據(jù)的問題。

函數(shù)也可以是靜態(tài)的,這樣就可以用類直接訪問,不需要新建對(duì)象來調(diào)用:

<?php 
  class marine
  {
    static $attackNumber = 10; //攻擊力的數(shù)字
    //這個(gè)函數(shù)表示機(jī)槍兵升級(jí)的運(yùn)行代碼
    staticfunction upgrade()
    {
      self::$attacknum++;
    }
  }
?>

如果科技建筑升級(jí)完畢,直接就調(diào)用這個(gè)函數(shù):

<?php
  marine::upgrade();
?>

四、繼承

兵營用來造機(jī)槍兵,坦克房用來制造坦克,他們都是建筑,但是卻有很多不同,如果用一個(gè)類“建筑”來表示,很困難。
但我們要保留他們的共性,比如都能飛行,不希望飛行的代碼在各個(gè)類重復(fù)寫,又要讓他們能各自獨(dú)立的生產(chǎn)不同的東西。
所以我們可以用繼承來處理,繼承表示父子關(guān)系,被繼承的叫父類,繼承的叫子類。用extends表示繼承

<?php 
  //建筑類
  class building
  {
    function fly()
    {
      //建筑飛行的代碼
    }
  }
  //兵營類
  class marineBuilding extends building
  {
    function createMarine()
    {
      //制造機(jī)槍兵的代碼
    }
  }
  //坦克房類
  class tankBuilding extends building
  {
    function createTank()
    {
      //制造坦克的代碼
    }
  }
?>

接下來,我們看看繼承產(chǎn)生的效果:

<?php 
  //如果造了一個(gè)兵營:
  $mb1 = new marineBuilding();
  //一旦他需要飛行,就可以直接使用建筑類的函數(shù)fly(),盡管兵營類的定義里沒有這個(gè)函數(shù)
  $mb1->fly();
  //而他要制造機(jī)槍兵的時(shí)候:
  $mb1->createMarine();
?>

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

五、訪問控制

如果用$attackNumber = 10表示屬性的話,系統(tǒng)默認(rèn)是public $attackNumber = 10,所以建議這樣寫:

<?php 
  class marine
  {
    public static $attackNumber = 10; //攻擊力的數(shù)字
  }
?>

public表示這個(gè)屬性是公共的,也就是在任何地方都可以訪問和操作的。

但這就存在一些問題,如果有玩家知道了類marine的一些代碼結(jié)構(gòu),那他做個(gè)簡(jiǎn)單的補(bǔ)丁程序,運(yùn)行的時(shí)候加載上去:

<?php
  //補(bǔ)丁
  marine::$attackNumber = 10000;
?>

這樣的話,他的機(jī)槍兵有10000的攻擊力,呵呵,這樣的話,誰打得過他!

為此我們要用private,表示這個(gè)屬性只有類里面的函數(shù)才能訪問:

<?php 
  class marine
  {
    private static $attackNumber = 10; //攻擊力的數(shù)字
    //這個(gè)函數(shù)表示機(jī)槍兵升級(jí)的運(yùn)行代碼
    function upgrade()
    {
      //這樣防止無限升級(jí)
      if(self::$attacknum<13)
      {
        self::$attacknum++;
      }
    }
  }
?>

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

六、重載

6.1、屬性重載

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

<?php 
  //地面部隊(duì)
  class groundArmy
  {
    public $attackNumber = 5;
  }
  //機(jī)槍兵
  class marine extends groundArmy
  {
    public $attackNumber = 10; //攻擊力的數(shù)字
  }
  $m1 = new marine();//新建一個(gè)機(jī)槍兵
  echo $m1->attackNumber;//顯示攻擊力為10
?>

6.2、函數(shù)重載

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

<?php
  //隱形能力類
  class concealAbility
  {
    //這個(gè)函數(shù)表示隱形的運(yùn)行代碼
    function conceal()
    {
      //隱形的運(yùn)行代碼
    }
  }
  //鬼兵類
  class ghost extends concealAbility
  {
    $energy = 150;
    //這個(gè)函數(shù)表示隱形的運(yùn)行代碼
    function conceal()
    {
      //隱形的運(yùn)行代碼
      //減少鬼兵的能量,$this表示當(dāng)前對(duì)象,也就是當(dāng)前這個(gè)鬼兵
      $this->energy -= 25;
    }
  }
  //黑暗圣堂類
  class DarkTemplar extends concealAbility
  {
    //這個(gè)函數(shù)表示隱形的運(yùn)行代碼
    function conceal()
    {
      //隱形的運(yùn)行代碼,不影響能量
    }
  }
  //新建一個(gè)鬼兵
  $g1 = new ghost();
  //顯示能量為150
  echo $g1->energy;
  //鬼兵隱形
  $g1->conceal();
  //顯示能量為125
  echo $g1->energy;
  //新建一個(gè)黑暗圣堂
  $d1 = new DarkTemplar();
  //黑暗圣堂隱形,他沒有能量屬性
  $g1->conceal();
?>

七、接口

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

<?php 
  interface concealAbility
  {
    public function conceal();
  }
  //飛行能力的接口
  interface flyAbility
  {
    public function fly();
  }
  //偵察機(jī)類
  class Wraith implements flyAbility, concealAbility
  {
    //這個(gè)函數(shù)表示偵察機(jī)飛行的運(yùn)行代碼
    function fly()
    {
      //飛行的運(yùn)行代碼
    }
    //這個(gè)函數(shù)表示偵察機(jī)隱形的運(yùn)行代碼
    function conceal()
    {
      //隱形的運(yùn)行代碼
    }
  }
?>

八、總結(jié)

我們討論了PHP面向?qū)ο蟮幕局R(shí),通過星際爭(zhēng)霸這一經(jīng)典的游戲來說明,大家可以看到面向?qū)ο蟮某醪阶饔谩?br /> 我們看到通過面向?qū)ο罂梢允勾a更加清晰,類將代碼組織起來,比較方便的重復(fù)使用。
同時(shí)對(duì)象也減少了變量的沖突,方便相關(guān)性數(shù)據(jù)的保存和使用。
如果要解決的問題涉及很多方面,面向?qū)ο罂梢匝莼龈屿`活和有技巧的方式,比如通常提到的設(shè)計(jì)模式,和很多框架。
當(dāng)然,面向?qū)ο笠灿腥秉c(diǎn),從上面的代碼可以看到,首先代碼就多了,簡(jiǎn)單的任務(wù)如果定義許多類,反而麻煩。
對(duì)于簡(jiǎn)單任務(wù),面向?qū)ο笠部赡苁勾a運(yùn)行的效率降低。
深入的探討,超出了本文的范圍。

更多關(guān)于PHP相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《php面向?qū)ο蟪绦蛟O(shè)計(jì)入門教程》、《PHP數(shù)組(Array)操作技巧大全》、《PHP基本語法入門教程》、《PHP運(yùn)算與運(yùn)算符用法總結(jié)》、《php字符串(string)用法總結(jié)》、《php+mysql數(shù)據(jù)庫操作入門教程》及《php常見數(shù)據(jù)庫操作技巧匯總

希望本文所述對(duì)大家PHP程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • Yii2 rbac權(quán)限控制之菜單menu實(shí)例教程

    Yii2 rbac權(quán)限控制之菜單menu實(shí)例教程

    這篇文章主要介紹了Yii2 rbac權(quán)限控制之菜單menu實(shí)例教程的相關(guān)資料,需要的朋友可以參考下
    2016-04-04
  • PHP 獲取客戶端 IP 地址的方法實(shí)例代碼

    PHP 獲取客戶端 IP 地址的方法實(shí)例代碼

    這篇文章主要介紹了PHP 獲取客戶端 IP 地址的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下
    2018-11-11
  • PHP生成word文檔的三種實(shí)現(xiàn)方式

    PHP生成word文檔的三種實(shí)現(xiàn)方式

    本篇文章主要介紹了PHP生成word的三種實(shí)現(xiàn)方式,利用php將內(nèi)容寫入Word中,有需要的可以了解一下。
    2016-11-11
  • laravel-admin 中列表篩選方法

    laravel-admin 中列表篩選方法

    今天小編就為大家分享一篇laravel-admin 中列表篩選方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-10-10
  • 實(shí)例講解YII2中多表關(guān)聯(lián)的使用方法

    實(shí)例講解YII2中多表關(guān)聯(lián)的使用方法

    最近工作中遇到了YII2多表關(guān)聯(lián)的相關(guān)問題,發(fā)現(xiàn)網(wǎng)上這方面的資料并不多,所以想著自己整理下吧,方便自己在以后需要的時(shí)候或者有需要的朋友們參考學(xué)習(xí),下面這篇文章主要給大家介紹了關(guān)于YII2中多表關(guān)聯(lián)的使用方法,需要的朋友下面來一起看看吧。
    2017-07-07
  • PHP將敏感文字內(nèi)容替換為星號(hào)的操作方法

    PHP將敏感文字內(nèi)容替換為星號(hào)的操作方法

    在PHP中,將敏感文字用星號(hào)替換通常涉及到字符串的搜索和替換操作,下面是一個(gè)基本的示例,展示如何將特定的敏感詞替換為星號(hào),感興趣的朋友跟隨小編一起看看吧
    2024-04-04
  • 淺析php創(chuàng)建者模式

    淺析php創(chuàng)建者模式

    本文通過實(shí)例向我們展示了php設(shè)計(jì)模式中的創(chuàng)建者模式,及創(chuàng)建者模式所應(yīng)用的場(chǎng)景,這里推薦給大家。
    2014-11-11
  • PHP循環(huán)結(jié)構(gòu)實(shí)例講解

    PHP循環(huán)結(jié)構(gòu)實(shí)例講解

    這篇文章主要介紹了PHP循環(huán)結(jié)構(gòu)實(shí)例講解,需要的朋友可以參考下
    2014-02-02
  • Yii框架分頁技術(shù)實(shí)例分析

    Yii框架分頁技術(shù)實(shí)例分析

    這篇文章主要介紹了Yii框架分頁技術(shù),結(jié)合實(shí)例形式詳細(xì)分析了Yii框架相關(guān)控制器、模型與視圖使用技巧,需要的朋友可以參考下
    2019-08-08
  • PHP解密Unicode及Escape加密字符串

    PHP解密Unicode及Escape加密字符串

    在json中不支持中文,用它傳送中文數(shù)據(jù)就會(huì)出現(xiàn)數(shù)據(jù)丟失或者亂碼,必須在傳送前對(duì)要發(fā)送的字符串進(jìn)行編碼,由于傳送過去需要用js進(jìn)行數(shù)據(jù)解析,考慮 到j(luò)s中有unescape函數(shù),故若在php中有個(gè)escape函數(shù),對(duì)數(shù)據(jù)進(jìn)行編碼,在客戶端用unescape進(jìn)行 解碼,這樣就會(huì)方便很多。
    2015-05-05

最新評(píng)論