1. 程式人生 > >淺談PHP面向物件程式設計(七)

淺談PHP面向物件程式設計(七)

7.0 抽象類與介面


 

當定義一個類時,常常需要定義一些方法來描述該類的行為特徵、但有時這些方法的實現方式是無法確定的,此時就可以使用抽象類和介面。

抽象類和介面用於提高程式的靈活性、抽象類是一種特殊的類,而介面又是一種待殊的抽象類。

接下來本節將針對抽象類和介面進行詳細講解。

7.1 抽象類


 

當在定義一個類的 時候,其中所霜的某些方法暫時並不能完全定義出來,而是讓其繼承的類來實現,此時就可以用到抽象類。

比如定又一個動物類,每種動物有一“叫” 的方法,面每種動物叫的方式不同,因此可以將動物類定義為一個抽象類。

定義抽象類需要使用 abstract 

關鍵字來修飾,語法格式具體如下:

1 abstract class  類名{
2       
3    //類成員
4   
5 }

由於每種動物叫的方式不同,所以需要將動物同的shut方法定義成抽象的, 即只有方法宣告面設有方法體的方法,在子類繼承時再來編寫該方法的具體實規,這種特珠的方法稱為抽象方法,其語法格式如下

1 abstract function 方法名 ();

為了更好的理解抽象類和抽象方法的使用,接下來t通過個案例來演示

例7-19

 1 <?php
 2      //使用abstract關鍵字宣告一個抽象類 
 3      abstract
class Animal{ 4 //在抽象類中宣告抽象方法 5 abstract public function shout(); 6 } 7 //定義Dog類繼承自Animal類 8 class Dog extends Animal{ 9 //實現抽象方法shout() 10 public function shout() 11 { 12 echo "汪汪......<br>"; 13 } 14 } 15 //
定義Cat類繼承自Animal類 16 class Cat extends Animal{ 17 //實現抽象方法shout() 18 public function shout() 19 { 20 echo "喵喵......<br>"; 21 } 22 } 23 $dog=new Dog(); 24 $dog->shout(); 25 $cat=new Cat(); 26 $cat->shout(); 27 ?>

 

執行結果

例7-19中,第3-6行程式碼定義了一個抽象類Animal. 然後使Dog類和Cat類繼承Animal類並實現抽象方法shout(). 最後分別呼叫cat物件和dog物件的shout()方法,輸出不同動物對應的叫聲

注意:

(1)抽象類不能被例項化。

(2)抽象類可以沒有抽象方法,但有抽象方法的抽象關才有意義,一旦類包含了抽象方法,則這個類必須宣告為abstract。

(3)抽象關中可以有非抽象方法、成員屬性和常量。

(4)抽象方法不能有函式體,它只能存在於抽象類中。

(5)如果一個類繼承了某個抽象類,則它必須實現該抽象類的所有抽象方法、除非它自己也宣告為抽象類。

 

7.2 介面


 

如果一個抽象類中的所有方法都是抽象的、則可以將這個類用另外一種方式來定義。即介面。在定義介面時,需要使用interface關鍵字,具體示例程式碼如下:

1 interface Animal{
2 
3    public function run ();
4 
5    public function breathe();  
6 
7 }

定義介面與定義一個標準的類類似,但其中定義的所有的方法都是空的。

需要注意的是介面中的所有方法都是公有的,也不能使用 final關鍵字來修飾

由於介面中定義的都是抽象方法,沒有具體實現,需要通過類來實現介面。實現介面使用 implements 關鍵字。

接下來通過一個案例來學習,如例7-20 所示

 

 1 <?php
 2      //定義Animal介面
 3      interface  Animal{
 4          public function run();
 5          public function shout();
 6      }
 7      //定義Dog類,實現了Animal介面
 8      class Dog implements Animal{
 9           public function run(){
10               echo "狗在奔跑<br>";
11          }
12          public function shout(){
13              echo "汪汪……<br>";
14          }
15      }
16      //定義Cat類,實現了Animal介面
17     class Cat implements Animal{
18          public function run(){
19              echo "貓在奔跑<br>";
20         }
21         public function shout(){
22             echo "喵喵……<br>";
23         }
24      }
25     $cat=new Cat();
26     $cat->run();
27     $cat->shout();
28     $dog=new Dog();
29     $dog->run();
30     $dog->shout();
31 ?>

 

 執行結果

在例7-20中,首先定義了介面Animal,在介面Animal中聲明瞭抽象方法run()和shout(). 然後分別通過Cat類和Dog類實現了Animal介面最後通過cat和dog物件呼叫run()和shout()方法。
在PHP中類是單繼承的,但一個類卻可以實現多個介面,並且這些介面之間用逗號分展開,接下來通過一個具體的案例來學習, 如例7-21所示。 

例7-21

 1  <?php
 2      //定義Animal介面
 3      interface  Animal{
 4          public function run();
 5          public function shout();
 6      }
 7      //定義LandAnimal介面
 8      interface  LandAnimal{
 9          public function LiveOnLand();     
10      }
11     //定義Dog類,實現了Animal和LandAnimal介面
12     class Dog implements Animal,LandAnimal{
13          public function LiveOnLand(){
14             echo"狗在陸地上生活<br>";
15         }
16          public function run(){
17               echo "狗在奔跑<br>";
18          }
19          public function shout(){
20             echo "汪汪……<br>";
21         }
22     }
23     $dog=new  Dog();
24     $dog->LiveOnLand();
25     $dog->run();
26     $dog->shout();
27 ?>

 

執行結果

在例7-21中,動物類Dog同時實現了介面Animal和LandAnimal,

通過dog物件呼叫了LandAnimal中的LiveOnLand()方法

和Animal介面中的run()和shout()方法

擴充套件-繼承和介面的配合使用


 

在使用implements關鍵宇實現介面的同 時,還可以使用extends 關鍵字繼承一個類。

即在繼承一個類的同時實現介面,但一定要先使用extends繼承一個類,再使用implements實現介面,

具體示例如下所示:

1 class 類名 extends 父類名 implements 介面1,介面2,....介面n{
2 
3      //實現所有介面中的抽象方法
4 
5 }

 

 

PHP的單繼承機制可保證類的純潔性,比C++中的多繼承機制簡潔。

但是不可否認,對子類功能的擴充套件有一定影響。

所以我們認為實現介面可以看作是對繼承的一種補充。

實現介面可在不打破繼承關係的前提下,對某個類功能擴充套件,非常靈活。