程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> PHP綜合 >> PHP面向對象編程專題8

PHP面向對象編程專題8

編輯:PHP綜合

上例輸出結果為:
執行結果
你所調用的函數:demo(參數:Array ( [0] => one [1] => two [2] => three ) )不存在!
this is a test.
19.抽象方法和抽象類
在OOP 語言中,一個類可以有一個或多個子類,而每個類都有至少一個公有方法做為外部代碼
訪問其的接口。而抽象方法就是為了方便繼承而引入的,我們先來看一下抽象類和抽象方法的定義
再說明它的用途。
什麼是抽象方法?我們在類裡面定義的沒有方法體的方法就是抽象方法,所謂的沒有方法體指
的是,在方法聲明的時候沒有大括號以及其中的內容,而是直接在聲明時在方法名後加上分號結束,
另外在聲明抽象方法時還要加一個關鍵字“abstract”來修飾;
例如:
abstract function fun1();
abstract function fun2();
上例是就是“abstract”修飾的沒有方法體的抽象方法“fun1()”和“fun2()”,不要忘記抽象
方法後面還要有一個分號;那麼什麼是抽象類呢?只要一個類裡面有一個方法是抽象方法,那麼這
個類就要定義為抽象類,抽象類也要使用“abstract”關鍵字來修飾;在抽象類裡面可以有不是抽
象的方法和成員屬性,但只要有一個方法是抽象的方法,這個類就必須聲明為抽象類,使用
“abstract”來修飾。
例如:
代碼片斷
abstract class Demo
{
var $test;
abstract function fun1();
abstract function fun2();
function fun3()
{
… .
}
}
上例中定義了一個抽象類“Demo”使用了“abstract”來修飾, 在這個類裡面定義了一個成員
屬性“$test”,和兩個抽象方法“fun1”和“fun2”還有一個非抽象的方法fun3();那麼抽象類我
們怎麼使用呢?最重要的一點就是抽象類不能產生實例對象,所以也不能直接使用,前面我們多次
提到過類不能直接使用,我們使用的是通過類實例化出來的對象,那麼抽象類不能產生實例對象我
們聲明抽象類有什麼用呢?我們是將抽象方法是作為子類重載的模板使用的,定義抽象類就相當於
定義了一種規范,這種規范要求子類去遵守,子類繼承抽象類之後,把抽象類裡面的抽象方法按照
子類的需要實現。子類必須把父類中的抽象方法全部都實現,否則子類中還存在抽象方法,那麼子
類還是抽象類,還是不能實例化對;為什麼我們非要從抽象類中繼承呢?因為有的時候我們要實現
一些功能就必須從抽象類中繼承,否則這些功能你就實現不了,如果繼承了抽象類,就要實現類其
中的抽象方法;
代碼片斷
<?
abstract class Demo
{
var $test;
abstract function fun1();
abstract function fun2();
function fun3()
{
… .
}
}
$demo=new Demo(); //抽象類為能產生實例對象,所以這樣做是錯的,實例化對象交給子類
class Test extends Demo
{
function fun1()
{

} function fun2()
{

}
}
$test=new Test(); //子類可以實例化對象,因為實現了父類中所有抽象方法
?>
20. PHP5 接口技術
PHP 與大多數面向對象編程語言一樣,不支持多重繼承.也就是說每個類只能繼承一個父類.為
了解決這個問題,PHP 引入了接口,接口的思想是指定了一個實現了該接口的類必須實現的一系列
方法。接口是一種特殊的抽象類,抽象類又是一種特殊的類,所以接口也是一種特殊的類,為什麼
說接口是一種特殊的抽象類呢?如果一個抽象類裡面的所有的方法都是抽象方法,那麼我們就換一
種聲明方法使用“接口”;也就是說接口裡面所有的方法必須都是聲明為抽象方法,另外接口裡面
不能聲明變量,而且接口裡面所有的成員都是public 權限的。所以子類在實現的時候也一定要使
用public 權限實限。
聲明一個類的時候我們使用的關鍵字是“class”,而接口一種特殊的類,使用的關鍵字是
“interface”;
類的定義:class 類名{ … },接口的聲明:interface 接口名{ … }
代碼片斷
<?PHP
//定義一個接口使用interface 關鍵字,“One”為接口名稱
interface One
{
//定義一個常量
const constant = 'constant value';
//定義了一個抽象方法”fun1”
public function fun1();
//定義了抽象方法”fun2”
public function fun2();
}
?>
上例中定義了一個接口“one”,裡面聲明了兩個抽象方法“fun1”和“fun2”,因為接口裡
面所有的方法都是抽象方法,所以在聲明抽象方法的時候就不用像抽象類那樣使用“abstract”這
個關鍵字了,默認的已經加上這個關鍵字,另外在接口裡邊的“public”這個訪問權限也可以去掉,
因為默認就是public 的,因為接口裡所有成員都要是公有的,所在對於接口裡面的成員我們就不
能使用“private”的和“protected”的權限了,都要用public 或是默認的。另外在接口裡面我
們也聲明了一個常量“constant”,因為在接口裡面不能用變量成員,所以我們要使用const 這個
關鍵字聲明。
因為接口是一種特殊的抽象類,裡面所有的方法都是抽象方法,所以接口也不能產生實例對象;
它也作為一種規范,所有抽象方法需要子類去實現。
我們可以使用“extends”關鍵字讓一個接口去繼承另一個接口;
代碼片斷
<?PHP
//使用”extends”繼承另外一個接口
interface Two extends One
{
function fun3();
function fun4();
}
?>
而我們定義一個接口的子類去實現接口中全部抽象方法使用的關鍵字是“implements”,而不
是我們前面所說的“extends”;
代碼片斷
<?PHP
//使用“implements”這個關鍵字去實現接口中的抽象方法
class Three implements One
{
function fun1()
{
… .
} function fun2()
{
… .
}
}
//實現了全部方法,我們去可以使用子類去實例化對象了
$three=new Three();
?>
我們也可以使用抽象類,去實現接口中的部分抽象方法,但要想實例化對象,這個抽象類還要
有子類把它所有的抽象方法都實現才行;
在前面我們說過,PHP 是單繼承的,一個類只能有一父類,但是一個類可以實現多個接口,就
相當於一個類要遵守多個規范,就像我們不僅要遵守國家的法律,如果是在學校的話,還要遵守學
校的校規一樣;
代碼片斷
<?PHP
//使用implements實現多個接口
class Four implemtns 接口一, 接口二, … .
{
//必須把所有接口中的方法都要實現才可以實例化對象。
}
?>
PHP 中不僅一個類可以實現多個接口,也可以在繼承一個類的同時實現多個接口, 一定要先
繼承類再去實現接口;
代碼片斷
<?PHP
//使用extends 繼承一個類,使用implements 實現多個接口
class Four extends 類名一implemtns 接口一, 接口二, … .
{
//所有接口中的方法都要實現才可以實例化對象
… … … ..
}?
>
21.多態的應用
多態是除封裝和繼承之外的另一個面向對象的三大特性之一,我個人看來PHP 中雖然可以實現
多態,但和C++還有Java 這些面向對象的語言相比,多態性並不是那麼突出,因為PHP 本身就是一
種弱類型的語言,不存在父類對象轉化為子類對象或者是子類對象轉化為父類對象的問題,所以多
態的應用並不是那麼的明顯;所謂多態性是指一段程序能夠處理多種類型對象的能力,比如說在公
司上班,每個月財務發放工資,同一個發工資的方法,在公司內不同的員工或是不同職位的員工,
都是通過這個方法發放的,但是所發的工資都是不相同的。所以同一個發工資的方法就出現了多種
形態。對於面向對象的程序來說,多態就是把子類對象賦值給父類引用,然後調用父類的方法,去
執行子類覆蓋父類的那個方法,但在PHP 裡是弱類型的,對象引用都是一樣的不分父類引用,還是
子類引用。
我們現在來看一個例子,首先還是要使用多態就要有父類對象和子類對象的關系。做一個形狀
的接口或是抽象類作為父類,裡面有兩個抽象方法,一個求周長的方法,另一個是求面積的方法;
這接口的子類是多種不同的形狀,每個形狀又都有周長和面積,又因為父類是一個接口,所以子類
裡面就必須要實現父類的這兩個周長和面積的抽象方法,這樣做的目的是每種不同形狀的子類都遵
守父類接口的規范,都要有求周長和求面積的方法。
代碼片斷
<?
//定義了一個形狀的接口,裡面有兩個抽象方法讓子類去實現
interface Shape
{
function area();
function perimeter();
}
//定義了一個矩形子類實現了形狀接口中的周長和面積
class Rect implements Shape
{
private $width;
private $height;
function __construct($width, $height)
{
$this->width=$width;
$this->height=$height;
} function area()
{
return "矩形的面積是:".($this->width*$this->height);
} function perimeter()
{
return "矩形的周長是:".(2*($this->width+$this->height));
}
}
//定義了一個圓形子類實現了形狀接口中的周長和面積
class Circular implements Shape
{
private $radius;
function __construct($radius)
{
$this->radius=$radius;
} function area()
{
return "圓形的面積是:".(3.14*$this->radius*$this->radius);
} function perimeter()
{
return "圓形的周長是:".(2*3.14*$this->radius);
}
}
//把子類矩形對象賦給形狀的一個引用
$shape=new Rect(5, 10);
echo $shape->area()."<br>";
echo $shape->perimeter()."<br>";
//把子類圓形對象賦給形狀的一個引用
$shape=new Circular(10);
echo $shape->area()."<br>";
echo $shape->perimeter()."<br>";
?>
上例執行結果:
執行結果
矩形的面積是:50
矩形的周長是:30
圓形的面積是:314
圓形的周長是:62.8
通過上例我們看到,把矩形對象和圓形對象分別賦給了變量$shape,調用$shape 引用中的面積
和周長的方法,出現了不同的結果,這就是一種多態的應用,其實在我們PHP 這種弱類形的面向對
象的語言裡面,多態的特性並不是特別的明顯,其實就是對象類型變量的變項應用。
22.把對象串行化
有時候需要把一個對象在網絡上傳輸,為了方便傳輸,可以把整個對象轉化為二進制串,等到
達另一端時,再還原為原來的對象,這個過程稱之為串行化, 就像我們現在想把一輛汽車通過輪
船運到美國去,因為汽車的體積比較大,我們可以把汽車拆開成小的部件,然後我們把這些部件通
過輪船運到美國去,到了美國再把這些部件組裝回汽車。
有兩種情況我們必須把對象串行化,第一種情況就是把一個對象在網絡中傳輸的時候要將對象
串行化,第二種情況就是把對象寫入文件或是數據庫的時候用到串行化。
串行化有兩個過程,一個是串行化,就是把對象轉化為二進制的字符串,我們使用serialize()
函數來串行化一個對象,另一個是反串行化,就是把對象轉化的二進制字符串再轉化為對象, 我
們使用unserialize()函數來反串行化一個對象.
PHP 中serialize()函數的參數為對象名,返回值為一個字符串,Serialize()返回的字符串含
義模糊,一般我們不會解析這個串來得到對象的信息,我們只要把返回來的這個字符串傳到網絡另
一端或是保存到方件中即可。
PHP 中unserialize()函數來反串
-EOF

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved