您好,登錄后才能下訂單哦!
抽象類與接口的區別是什么,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
定義為抽象的類不能被實例化。
任何一個類,如果它里面至少有一個方法是被聲明為抽象的,那么這個類就必須被聲明為抽象的。
被定義為抽象的方法只是聲明了其調用方式(參數),不能定義其具體的功能實現。
繼承一個抽象類的時候,子類必須定義父類中的所有抽象方法,這些方法的訪問控制必須和父類中一樣(或者更為寬松)。
<?phpabstract class AbstractClass{//抽象方法 -- 強制要求子類定義這些方法// 我們的抽象方法僅需要定義需要的參數abstract protected function getValue();abstract protected function prefixValue($prefix);abstract protected function prefixName($name);//普通方法(非抽象)public function printOut(){print $this->getValue() . "\n";}}//子類繼承抽象類class ConcreteClass1 extends AbstractClass{protected function getValue() {return "ConcreteClass1";}//訪問權限可以比父類更寬松或同權限public function prefixValue($prefix) {return "{$prefix}ConcreteClass1";}// 我們的子類可以定義父類簽名中不存在的可選參數public function prefixName($name, $separator = ".") {if ($name == "Pacman") {$prefix = "Mr";} elseif ($name == "Pacwoman") {$prefix = "Mrs";} else {$prefix = "";}return "{$prefix}{$separator} {$name}";}}$class1 = new ConcreteClass1;$class1->printOut();echo $class1->prefixValue('FOO_') ."\n";echo $class1->prefixName("Pacman"), "\n";//以上例程會輸出://ConcreteClass1 //FOO_ConcreteClass1//Mr. Pacman
使用接口 (interface) 關鍵字,可以指定某個類必須實現哪些方法,但不需要定義這些方法的具體內容,就像定義一個標準的類一樣,但其中定義所有的方法都是空的。
接口中定義的所有方法都必須是公有,這是接口的特性。
在接口中定義一個構造方法是被允許的。在有些場景下這可能會很有用,例如用于工廠模式時。
接口中也可以定義常量。接口常量和類常量的使用完全相同,但是不能被子類或子接口所覆蓋。
要實現一個接口,使用 implements
操作符。類中必須實現接口中定義的所有方法,否則會報一個致命錯誤。
類可以實現多個接口,用逗號來分隔多個接口的名稱。(注意:在 PHP 5.3.9 之前,實現多個接口時,接口中的方法不能有重名,因為這可能會有歧義。在最近的 PHP 版本中,只要這些重名的方法簽名相同,這種行為就是允許的。)
接口也可以繼承,通過使用 extends 操作符。
類要實現接口,必須使用和接口中所定義的方法完全一致的方式。否則會導致致命錯誤。
<?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;}}
<?phpinterface 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){}}
<?phpinterface 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(){}}
<?phpinterface a{const b = 'Interface constant';}// 輸出接口常量echo a::b;// 錯誤寫法,因為常量不能被覆蓋。接口常量的概念和類常量是一樣的。class b implements a{const b = 'Class constant';}
抽象類和接口分別能直接實例化嗎?
都不能直接實例化
抽象類的方法可以存在方法體嗎?
抽象類中,定義為抽象方法的不可以存在方法體,抽象類中普通方法可以存在方法體。
抽象方法和普通方法的區別是什么?
抽象方法只是聲明了其調用方式(參數),不能定義其具體的功能實現,普通方法可以定義具體的實現。
抽象方法可以是靜態方法嗎?
可以(PHP5+版本會出現嚴格模式提示,PHP7+無錯,均可以運行)
抽象類可以存在成員屬性嗎?所有等級都可以嗎?
可以存在成員屬性,所有等級都可以,但是子類能直接調用的只有公開屬性
接口的方法可以存在方法體嗎?
接口方法不可以有方法體
接口可以存在成員屬性嗎?所有等級都可以嗎?
不可以存在,接口不包括成員屬性
普通類可以同時繼承多個抽象類嗎?如果可以如何實現?
抽象類不可以多繼承 (多繼承實現可以使用Trait)
普通類可以同時實現多個接口類嗎?如果可以如何實現?
可以,類可以實現多個接口,用逗號來分隔多個接口的名稱。
抽象類可以實現接口嗎?如果可以,那抽象類需要實現接口定義的方法體嗎?
抽象類可以實現接口,并且不需要實現接口的方法,但是普通類繼承抽象類后需要全部實現
普通類可以既繼承抽象類又實現接口嗎?
可以
看完上述內容,你們掌握抽象類與接口的區別是什么的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。