* **抽象**类可以没有抽象方法,但是抽象方法必须放在抽象类中,除此之外,抽象类和普通类无差别;如可以有方法实现,可以定义属性等等。。。抽象方法不必实现具体的功能,由子类来完成,但是,抽象方法不能有花括号,必须在子类中重写,抽象类是**不能被实例化**;继承抽象类的子类,如果不实现所有抽象方法,那么该子类也为抽象类
```
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;
}
}
```