1. 程式人生 > >PHP面向物件開發基礎與例項

PHP面向物件開發基礎與例項




<1> 面向物件涉及到軟體開發的各個方面,如面向物件分析(OOA),面向物件的設計(OOD),面向物件的程式設計實現(OOP)。


<2> 面向物件的要素包括:抽象性;封裝性;共享性;強調物件結構而不是程式結構。


<3> 封裝,繼承與多型是面向物件開發的三大特點,缺一不可。


<4> 類(Class)實際上是對某種型別的物件定義變數和方法的原型。它包含有關物件動作方式的資訊,包括它的名稱、方法、屬性和事件。實際上它本身並不是物件,因為它不存在於記憶體中。當引用類的程式碼執行時,類的一個新的例項,即物件,就在記憶體中建立了。雖然只有一個類,但能從這個類在記憶體中建立多個相同型別的物件。


可以把類看作“理論上”的物件,也就是說,它為物件提供藍圖,但在記憶體中並不存在。從這個藍圖可以建立任何數量的物件。從類建立的所有物件都有相同的成員:屬性、方法和事件。但是,每個物件都象一個獨立的實體一樣動作。例如,一個物件的屬性可以設定成與同類型的其他物件不同的值。


1.類的成員屬性與成員方法


以下為引用內容:
/***
  * desteps.com  Michael
***/
<?php
class Bike{                    // 使用CLASS建立一個類
var $name;                    // 定義成員屬性
var $price;
function run () {             //定義成員方法       
return "1200km";
}
}
?>
物件的例項化


以下為引用內容:
/***
  * desteps.com  Michael
***/
<?php
class Bike{                                  // 使用CLASS建立一個類
var $name;                                  // 定義成員屬性
var $price;
function run () {                           //定義成員方法       
return "1200km";
}
}
$bk=new Bike();                         // 使用NEW函式例項化物件  
echo $bk->name;                      // 使用->訪問物件內容
?>


2.類的封裝
出於保護與安全的需要,對程式的相關屬性和方法進行隱藏。


封裝關鍵字


public : 全域性變數,在類的內外均可訪問。
      protected :保護屬性,只有在本類、子類、父類中可以訪問。
      private :私有屬性,只能在當前類中使用。 


使用 public 全域性變數,對其定義的物件既可以訪問,也可以修改,如:


以下為引用內容:
/***
  * desteps.com  Michael
***/
<?php
class mobile{
public $name;                               // $name 具有公共屬性
function __construct($name=""){
$this->name=$name;
}
}
$mb1=new mobile("手機");
$mb1->name="行動電話";             // 可以改變name的值
echo $mb1->name;                      // 可以訪問name的值 
?>
使用 private 私有變數,將物件的屬性私有化。


以下為引用內容:
/***
  * desteps.com  Michael
***/
<?php
class mobile{
private $name;                                // $name具有私有屬性
function __construct($name=""){
$this->name=$name;
}
function call(){                                 // 通過公有的物件方法下$this關鍵字來訪問name的值
 return $this->name."正在開機中,請稍候......";
 }
}
$mb1=new mobile("手機");
echo $mb1->call();                          // 通過訪問公有的物件方法call來訪問私有了的name的值
?>
3.建構函式與解構函式
系統變數:$this


用來訪問當前物件中的物件屬性和物件方法。
      [注] $this僅能在當前物件中使用。


建構函式


以下為引用內容:
/***
  * desteps.com  Michael
***/
class Bike{
function __construct(){
//初始化操作
}
}
解構函式


能夠在物件釋放時自動被呼叫的方法。
      當物件內部的操作執行完畢時,__destruct()被呼叫,然後物件所使用的記憶體被釋放出來。


例項:


<1> $this 方式訪問物件


以下為引用內容:
/***
  * desteps.com  Michael
***/
<?php
class Bike{
public $name;
function sport(){
return "$this->name:健身";
}
function game(){
return "$this->name:比賽";
}
function traffic(){
return "上班";
}
}
$bk1=new Bike();
$bk2=new Bike();
$bk1->name="賽車";
$bk2->name="健身車";
echo $bk1->game(),"<hr align='left' width='160px'/>";
echo $bk2->sport(),",",$bk2->traffic();
?>
<2> __construct 函式


以下為引用內容:
/***
  * desteps.com  Michael
***/
<?php
class Bike{
public $name;
function __construct($name=""){
$this->name=$name;
}
 function sport(){
return "$this->name:健身";
}
function game(){
return "$this->name:比賽";
}
function traffic(){
return "上班";
}
}
$bk1=new Bike("賽車");
$bk2=new Bike("健身車");
echo $bk1->game(),"<hr align='left' width='160px'/>";
echo $bk2->sport(),",",$bk2->traffic();
?>


<3> 解構函式__destruct


以下為引用內容:
/***
  * desteps.com  Michael
***/
<?php
class Bike{
public $name;
function __construct($name=""){
$this->name=$name;
}
function sport(){
return "$this->name:健身";
}
function game(){
return "$this->name:比賽";
}
function traffic(){
return "上班";
}
function __destruct(){
 echo "<hr color='#ff6600' align='left' width='160px'/>********$this->name";
 }
}
$bk1=new Bike("賽車");
$bk2=new Bike("健身車");
echo $bk1->game(),"<hr align='left' width='160px'/>";
echo $bk2->sport(),",",$bk2->traffic();
?>
4,類的繼承與訪問


類的繼承


繼承關鍵字:extends ,子類(派生類)繼承父類(基類),利用 extends 單一繼承的方法,共享被繼承類(父類)的內容。


繼承規則


class1  extends  class2  extends   class3  
      [注] 子類與父類的屬性和方法應避免重名。


演示例項:


以下為引用內容:
/***
  * desteps.com  Michael
***/
<?php 
class ku{
function kx(){
return "基類中的內容<br/>";
}
}
class su extends ku{                     // 類的繼承
function sx(){
return "繼承類中的內容";
}
}
$su=new su();                               // 對繼承類SU進行例項化
echo $su->kx();                             // 繼承類SU是否已經繼承基類KU中的內容
?>
同時訪問基類和繼承類中的內容


以下為引用內容:
/***
  * desteps.com  Michael
***/
<?php 
class ku{
function kx(){
return "基類中的內容<br/>";
}
}
class su extends ku{
function sx(){
return $this->kx()."繼承類中的內容";        // 用this關鍵字來實現基類和繼承類內容的同時訪問

}
$su=new su();
echo $su->sx();
?>
5.基類方法的過載


基類方法的過載


在派生類裡使用與基類方法重名的方法名稱來執行過載。


基類方法的訪問


過載時需要呼叫原始基類的內容,再增加新的內容,可以使用:
      基類名::方法名稱


過載訪問演示例項


以下為引用內容:
/***
  * desteps.com  Michael
***/
<?php 
class ku{
function kx(){                    
return "基類中的內容<br/>";
}
}
class su extends ku{
function kx(){                                          // 與基類方法重名
return ku::kx()."繼承類中的內容";       // 過載的訪問

}
$su=new su();
echo $su->kx();
?>
用protected對基類方法進行封裝


以下為引用內容:
/***
  * desteps.com  Michael
***/
<?php 
class ku{
protected function kx(){                           //   用protected對基類方法進行封裝            
return "基類中的內容<br/>";
}
}
class su extends ku{
function kx(){
return ku::kx()."繼承類中的內容";

}
$su=new su();
echo $su->kx();
?>
[注]  用protected對基類方法進行封裝,可以在本類和繼承類中進行訪問;而private只能在本類中進行訪問。


6.抽象方法和抽象類


抽象的類


抽象類往往用來表徵我們在對問題領域進行分析、設計中得出的抽象概念,是對一系列看上去不同,但是本質上相同的具體概念的抽象。
      PHP中使用abstract來宣告一個抽象類或抽象方法。


定義抽象方法和抽象類


類中至少有一個方法是抽象的,這個類稱之為抽象類;
      如果定義抽象類須首先定義抽象方法。


以下為引用內容:
abstract class ku{
abstract function kx()
......
}
[注] 類中至少有一個抽象方法;
            抽象方法中沒有{  } ;
            抽象方法前必須要加abstract 。


抽象類的特點


不能被例項化,只能被繼承。
      繼承的派生類當中要把所有抽象方法過載才能例項化。


抽象方法過載演示例項


以下為引用內容:
/***
  * desteps.com  Michael
***/
<?php 
abstract class ku{
abstract function kx1();
abstract function kx2();
abstract function kx3();
function kx4(){
return "一共有三種抽象方法,這是過載的";
}
}
class su extends ku{
function kx1(){
echo "第一種抽象方法";
}
function kx2(){
echo ku::kx4()."第二種抽象方法";
}
function kx3(){
echo "第三種抽象方法";

}
$su=new su();
$su->kx2();
?>
7.final關鍵字詳解


關鍵字 final


用來定義類和方法的一個關鍵字,當定義類時該類將不能被繼承;當定義方法時該方法將不能被過載。


以下為引用內容:
final  class cla{
final function fun(){
......
}
......
}
類的繼承與方法過載的示例


以下為引用內容:
/***
  * desteps.com  Michael
***/
<?php
class mobile{
public $name="手機";
function call(){
return $this->name."具有電話功能<br/>";
}
}
class mmobile extends mobile{
function call(){
echo mobile::call(). "音樂手機繼承了手機原有的電話功能"; 
}
}
$mb1=new mmobile();
echo $mb1->call();
?>
當使用 final 來定義方法時,該方法不能被過載。


8.靜態成員及其訪問


self 關鍵字


用來用類訪問當前類中的內容的關鍵字,類似 $this 關鍵字,但 $this 需要類例項化以後才可以使用,而 self 則可以直接訪問當前類中的內部成員(屬性或方法)。


self ::  類內部成員(屬性或方法)等同:類名稱 ::  類內部成員(屬性或方法)


[注] self 一般用來訪問類中的“靜態成員”,常量或其它定義內容。


static 關鍵字


用來定義類的靜態屬性或方法,可以在類未被例項化時使用,靜態屬性單獨佔用記憶體,而不會因建立多個物件時而導致同樣的方法或屬性重複佔用。


以下為引用內容:
class cla{
static $name;
static function fun(){
......
}
}
[注] 靜態方法內部禁止出現非靜態內容。


靜態成員的訪問


<1> 在類內部訪問靜態成員:
      類名稱 :: 靜態成員
      self :: 靜態成員


<2> 在類外部訪問靜態成員:
      類名稱 :: 靜態成員


類屬性的靜態化及其訪問


以下為引用內容:
/***
  * desteps.com  Michael
***/
 <?php
final class mobile{
static $name="手機";
final function call(){
return self::$name."具有電話功能<br/>";
}
}
$mb1=new mobile();
echo $mb1->call();
?>
9.const關鍵字詳解


const 關鍵字


在定義一個常量的時候我們可以使用 const 來修飾這個常量;


只能申明類中的成員屬性而不能申明成員方法;


使用 const 修飾的常量與其它的常量有點不同的是常量名前不要使用”$”;


當然這個常量值也是不能修改的,一旦定義就不能在程式的任何地方進行“人為”的修改;


還有就是使用 const 來定義當然也遵守其它常量的命名規則――使用大字的字母。


演示例項


以下為引用內容:
/***
  * desteps.com  Michael
***/
 <?php
final class mobile{
const NAME="手機";
static function call(){
return self::NAME."具有電話功能";
}
}
$mb=new mobile;
echo $mb->call();
?>
輸出:手機具有電話功能


10.介面的建立與引用


介面的概念


介面是一種成員屬性全部為抽象或常量的特殊抽象類。


介面與抽象類的區別
      抽象類:
      <1> 類中至少有一個抽象方法。
      <2> 抽象方法前需加 abstract 。
      介面:
      <1> 類中全部為抽象方法。
      <2> 抽象方法前不用加 abstract 。
      <3> 定義抽象方法時,抽象方法為公共屬性( public )。
      <4> 成員屬性必須為常量。


介面與抽象類的共同點
      <1> 本身不能被例項化,必須被繼承或引用。
      <2> 繼承或引用後,需要把所有抽象方法過載方可使用。


建立介面


關鍵字:interface 
      格式:


以下為引用內容:
interface demo{
const NAME="常量";
function fun1();
function fun2();
}
介面的引用與規則


關鍵字:implements 。
      可以有多個引用,並用","分開。


設已有基類 mob ,介面demo1,demo2,demo3。


<1> 普通類引用介面


以下為引用內容:
class mob implements demo1,demo2,demo3{
......
}
<2> 抽象類引用介面


以下為引用內容:
abstract class mob implements demo1,demo2,demo3{
......
}
11.多型應用詳解


什麼是多型


多型是接抽象和繼承之後,面嚮物件語言的第三個特徵,具有表現多種形態的能力,在OOP中是指語言具有根據物件的型別以不同方法處理。
      OOP模式並不僅僅是很多函式和功能的集合,而是使用類、繼承、多型的方式使我們描述的物件程式碼更具有“物”的意義,幫助減少一些重複性的程式碼和條件的判斷。


運算子:instanceof


是PHP的一個型別運算子,用來測定一個給定的物件是否來自指定的物件類。


以下為引用內容:
class A{}
class B{}
$thing = new A ;
if ($thing instanceof A){
echo "A";
}
if($thing instanceof B){
echo "B";
}
多型的應用示例


假定現有兩個類UP和MP4,U盤(UP)和MP4分別插入電腦(PC)USB介面。


以下為引用內容:
/***
  * desteps.com  Michael
***/
 <?php
interface usb{                                                  // 建立一個USB介面
function type();                                                // 型號
function alert();                                                // 提示
}
class up implements usb{                            // UP
function type(){
echo "型號:2.0<br/>";
}
function alert(){
echo "正在檢查U盤驅動 . . . . . .";
}
}
class mp4 implements usb{                           //MP4
function type(){
echo"型號:1.0<br/>"; 
}
function alert(){
echo "正在檢查mp4驅動 . . . . . .";
}
}
class pc{                                                              // 建立一個電腦的類
function pcusb($wt){                                          // 電腦USB介面方法
$wt->type();                                                          // 判斷介面型別
$wt->alert();                                                          // 執行檢查驅動

}
$pc=new pc;
$up=new up;
$mp4=new mp4;
$pc->pcusb($up);                                                 // 在電腦介面上插入U盤時
?>
12.PHP面向物件之物件描述的配置


物件描述的配置


方法名:_ _ tostring()


可以直接列印物件控制代碼,從而獲得該方法的基本資訊或其它資訊。


tostring 方法的用法:


以下為引用內容:
class descript{
function __tostring(){
return " 描述descript類的一些基本資訊";
}
}
$ds=new descript ;
echo $ds;
tostring 方法演示例項


以下為引用內容:
/***
  * desteps.com  Michael
***/
 <?php
class descript{
public $name="tostring 方法";
function __tostring(){
return $this->name."可以直接列印物件控制代碼,從而獲得該方法的基本資訊。";
}
}
$ds=new descript;
echo $ds;
?>
執行結果:


tostring 方法可以直接列印物件控制代碼,從而獲得該方法的基本資訊。


13.PHP面向物件物件方法的異常處理


物件方法的異常處理


方法名:_ _call($funname,$arr_value)


呼叫一些不存在的物件方法的異常處理,使程式繼續正常執行。


call方法的用法:


以下為引用內容:
/***
  * desteps.com  Michael
***/
class dispose{
function __call($n,$v){
echo "錯誤的方法".$n;
echo "錯誤的引數".print_r($v);
}
}
call方法的演示例項


以下為引用內容:
/***
  * desteps.com  Michael
***/
 <?php
class dispose{
public $name="call 方法";
function __tostring(){
return $this->name."呼叫一些不存在的物件方法的異常處理,使程式繼續正常執行。<br/>";
}
function __call($n,$v){
echo "不存在的方法為:".$n."<br/>不存在的值是:";
echo print_r($v);
}
}
$ds=new dispose;
echo $ds;
$ds->noth("nothing",2050);
?>
執行結果:


call 方法呼叫一些不存在的物件方法的異常處理,使程式繼續正常執行。
      不存在的方法為:noth
      不存在的值是:Array ( [0] => nothing [1] => 2050 ) 1


14.PHP面向物件克隆物件方法詳解


克隆物件


方法名:_ _clone
      關鍵字:clone
      通過克隆的方式可以在記憶體中生成兩個一樣的物件或升級原物件。


克隆的原理


<1> 記憶體中只有一個物件


以下為引用內容:
$a=new cla;
$b=$a;
<2>記憶體中會有兩個物件


以下為引用內容:
$a=new cla;
$b=clone $a;
<3>clone 方法


以下為引用內容:
class cla{
function __clone(){
echo "克隆時自動初始化的函式";
}
}
clone(克隆)物件示例


以下為引用內容:
/***
  * desteps.com  Michael
***/
 <?php
class clo{
public $name="等於的方法";
function fun(){
return $this->name."只是將一個類賦值給另一個類,所以此時記憶體中仍是一個物件";
}
function __destruct(){
echo "<br/>清理了一個物件"; 
}
}
$ds=new clo;
$dt=$ds;
echo $dt->fun();
?>
執行結果:
      等於的方法只是將一個類賦值給另一個類,所以此時記憶體中仍是一個物件
      清理了一個物件


以下為引用內容:
/***
  * desteps.com  Michael
***/
 <?php
class clo{
public $name="等於方法";
function fun(){
return $this->name."克隆出了一個新的類,所以此時記憶體中有兩個物件";
}
function __destruct(){
echo "<br/>清理了一個物件"; 
}
function __clone(){
$this->name="clone 方法"; 
}
}
$ds=new clo;
$dt= clone $ds;
echo $dt->fun();
?>
執行結果:


clone 方法克隆出了一個新的類,所以此時記憶體中有兩個物件
      清理了一個物件
      清理了一個物件


15.PHP面向物件自動載入物件詳解


方法名:_ _autoload()


取得物件名稱並自動載入當前頁面。


自動載入方法


以下為引用內容:
function __autoload($class_n){
includ($class_n.".php");
}
$cla=new cla;
$clb=new clb;
等同於 include 方法


以下為引用內容:
include("cla.php");
include("clb.php");
自動載入物件示例


先新建兩個檔案作為載入物件(cla.php ;clb.php)


cla.php


以下為引用內容:
/***
  * desteps.com  Michael
***/
<?php 
class cla{
function fun1(){
echo "這是一個cla類";
}
}
?>
clb.php


以下為引用內容:
/***
  * desteps.com  Michael
***/
<?php
class clb{
function fun2(){
echo "這是一個clb類";
}
}
?>
引用檔案 auto.php


以下為引用內容:
/***
  * desteps.com  Michael
***/
<?php
function __autoload($name){
include("$name.php");
}
$cla=new cla;
$cla->fun1();
echo "<br/>";
$clb=new clb;
$clb->fun2();
?>