之前上學那會學習的專業是C#,工作中的php也在多個項目中,歷練成長了不少,不過今天被一個問題問到,php接口,一直知道有這麼一個東西存在,但是平時也沒有怎麼用到過接口,自己也查了下,先記錄學習一下,以後有項目能用到那就在好不過
書面定義
接口泛指實體把自己提供給外界的一種抽象化物(可以爲另一實體),用以由內部操作分離出外部溝通方法,使其能被修改內部而不影響外界其他實體與其交互的方式,就如面向對象程序設計提供的多重抽象化。接口可能也提供某種意義上的在講不同語言的實體之間的翻譯。人類與電腦等信息機器或人類與程序之間的接口稱爲用戶界面。電腦等信息機器硬件組件間的接口叫硬件接口。電腦等信息機器軟件組件間的接口叫軟件接口。
接口中定義的所有方法都必須是公有,這是接口的特性。
使用接口(interface),可以指定某個類必須實現哪些方法,但不需要定義這些方法的具體內容。
接口是通過 interface 關鍵字來定義的,就像定義一個標準的類一樣,但其中定義所有的方法都是空的。
關於interface
interface是C# 中接口操作的關鍵字,功能是把所需成員組合起來,以封裝一定功能的集合。它好比一個模板,在其中定義了對象必須實現的成員,通過類或結構來實現它。接口不能直接實例化,即ICount ic=new iCount()是錯的。接口不能包含成員的任何代碼,只定義成員本身。接口成員的具體代碼由實現接口的類提供。接口使用interface關鍵字進行聲明。
聲明格式
[attributes] [modifiers] interface identifier [: base-list] {interface-body} {;}
使用說明
1、attributes(可選):附加的定義性信息。
2、modifiers(可選): 允許使用的修飾符有 new 和四個訪問修飾符。分別是:new、public、protected、internal、 private。在一個接口定義中同一修飾符不允許出現多次,new 修飾符只能出現在嵌套接口中,表示覆蓋了繼承而來的同名成員。The public, protected, internal, and private 修飾符定義了對接口的訪問權限。
3、指示器和事件。
4、identifier:接口名稱。
5、base-list(可選):包含一個或多個顯式基接口的列表,接口間由逗號分隔。
6、interface-body:對接口成員的定義。
7、接口可以是命名空間或類的成員,並且可以包含下列成員的簽名: 方法、屬性、索引器 。
8、一個接口可從一個或多個基接口繼承。
接口這個概念在C#和Java中非常相似。接口的關鍵詞是interface,一個接口可以擴展一個或者多個其他接口。按照慣例,接口的名字以大寫字母"I"開頭。
接口實現(implements)
要實現一個接口,使用 implements 操作符。類中必須實現接口中定義的所有方法,否則會報一個致命錯誤。類可以實現多個接口,用逗號來分隔多個接口的名稱。
【注意】
1、實現多個接口時,接口中的方法不能有重名。
2、接口也可以繼承,通過使用 extends 操作符。
3、類要實現接口,必須使用和接口中所定義的方法完全一致的方式。否則會導致致命錯誤。
【常量】
接口中也可以定義常量。接口常量和類常量的使用完全相同,但是不能被子類或子接口所覆蓋。
舉個栗子
Example#1 接口示例
[php] view plain copy
- <?php
- // 聲明一個'iTemplate'接口
- interface iTemplate
- {
- public function setVariable($name, $var);
- public function getHtml($template);
- }
- // 實現接口
- // 下面的寫法是正確的
- class Template implements iTemplate
- {
- private $vars = array();
- public function setVariable($name, $var)
- {
- $this->vars[$name] = $var;
- }
- public function getHtml($template)
- {
- foreach($this->vars as $name => $value) {
- $template = str_replace('{' . $name . '}', $value, $template);
- }
- return $template;
- }
- }
- // 下面的寫法是錯誤的,會報錯,因爲沒有實現 getHtml():
- // Fatal error: Class BadTemplate contains 1 abstract methods
- // and must therefore be declared abstract (iTemplate::getHtml)
- class BadTemplate implements iTemplate
- {
- private $vars = array();
- public function setVariable($name, $var)
- {
- $this->vars[$name] = $var;
- }
- }
- ?>
Example2 可擴充的接口
[php] view plain copy
- <?php
- interface a
- {
- public function foo();
- }
- interface b extends a
- {
- public function baz(Baz $baz);
- }
- // 正確寫法
- class c implements b
- {
- public function foo()
- {
- }
- public function baz(Baz $baz)
- {
- }
- }
- // 錯誤寫法會導致一個致命錯誤
- class d implements b
- {
- public function foo()
- {
- }
- public function baz(Foo $foo)
- {
- }
- }
- ?>
Example3 繼承多個接口
[php] view plain copy
- <?php
- interface a
- {
- public function foo();
- }
- interface b
- {
- public function bar();
- }
- interface c extends a, b
- {
- public function baz();
- }
- class d implements c
- {
- public function foo()
- {
- }
- public function bar()
- {
- }
- public function baz()
- {
- }
- }
- ?>
Example4 使用接口常量
[php] view plain copy
- <?php
- interface a
- {
- const b = 'Interface constant';
- }
- // 輸出接口常量
- echo a::b;
- // 錯誤寫法,因爲常量不能被覆蓋。接口常量的概念和類常量是一樣的。
- class b implements a
- {
- const b = 'Class constant';
- }
- ?>
案例
[php] view plain copy
- <?php
- /**
- * An example of duck typing in PHP
- */
- interface CanFly {
- public function fly();
- }
- interface CanSwim {
- public function swim();
- }
- class Bird {
- public function info() {
- echo "I am a {$this->name}\n";
- echo "I am an bird\n";
- }
- }
- /**
- * some implementations of birds
- */
- class Dove extends Bird implements CanFly {
- var $name = "Dove";
- public function fly() {
- echo "I fly\n";
- }
- }
- class Penguin extends Bird implements CanSwim {
- var $name = "Penguin";
- public function swim() {
- echo "I swim\n";
- }
- }
- class Duck extends Bird implements CanFly, CanSwim {
- var $name = "Duck";
- public function fly() {
- echo "I fly\n";
- }
- public function swim() {
- echo "I swim\n";
- }
- }
- /**
- * a simple function to describe a bird
- */
- function describe($bird) {
- if ($bird instanceof Bird) {
- $bird->info();
- if ($bird instanceof CanFly) {
- $bird->fly();
- }
- if ($bird instanceof CanSwim) {
- $bird->swim();
- }
- } else {
- die("This is not a bird. I cannot describe it.");
- }
- }
- // describe these birds please
- describe(new Penguin);
- echo "---\n";
- describe(new Dove);
- echo "---\n";
- describe(new Duck);