* **抽象**類可以沒有抽象方法,但是抽象方法必須放在抽象類中,除此之外,抽象類和普通類無差別;如可以有方法實現,可以定義屬性等等。。。抽象方法不必實現具體的功能,由子類來完成,但是,抽象方法不能有花括號,必須在子類中重寫,抽象類是**不能被實例化**;繼承抽象類的子類,如果不實現所有抽象方法,那么該子類也為抽象類
```
abstract class People{
public $age = 18; //可以定義屬性
?public function say(){ //可以方法實現
echo "i am say";
}????
abstract public function run(); //方法聲明 不能有花括號,抽象類可以沒有抽象方法
}
```
* **繼承**類中,可以對繼承過來的方法重寫,甚至可以改變參數的個數,類型,但是會報warming提示說和抽象類的不兼容;對于抽象方法必須實現。把抽象轉化為一般方法,可以留空;
* 相比較抽象類,**接口**是不能有成員屬性和方法實現的,可以定義常量,相對與抽象類來說,接口的抽象更純潔,只有抽象方法,沒有其他元素,對于接口的實現,接口的**方法必須實現**,但是接口可以實現多個;
* **Trait**中的方法或屬性會**覆蓋**基類中的同名的方法或屬性,而本類會覆蓋Trait中同名的屬性或方法;traint和類差不多,但是可以被**use引入**,相對于接口,更加親民,而且跟class血緣更近,這么說的意思是,父類中的方法可以被traint覆蓋,本類可以覆蓋traint,引入多個traint時,如果有方法重復,會報一下錯誤Fatal error: Trait method eat has not been applied, because there are collisions with other trait methods on dog;
方法起別名時用 as ,方法沖突用insteadof
```
trait trait1{
public function eat(){
echo 'this is trait1 eat';
}
public function drive(){
echo 'this is trait1 drive';
}
}
trait trait2{
public function eat(){
echo 'this is trait2 eat';
}
public function drive(){
echo 'this is trait2 drive';
}
}
class dog{
use trait1, trait2{
trait1::eat insteadof trait2; // 方法沖突時的處理方法
trait1::drive insteadof trait2;
trait2::eat as eaten; // 方法別名
trait2::drive as driven;
}
}
```