如何区别Trait、接口和抽象类
一句话总结:1、Trait是特征,类似函数,为了解决单继承不能多复用的问题,有实现、能复用、能多use。
a、使用Trait的类可以在类的内部使用use关键字,静态属性和方法在类的内部用self::,非静态的在类的内部使用$this->,类的外部需要先new类,然后使用$对象->属性或方法。
b、把多个类中重复的属性、方法抽出来写在一个Trait里。
c、在类的内部可以use多个Trait。
d、不参与继承,只是把代码“复制”进需要使用Trait的类里。
e、最适合通用功能、工具方法。例如:
trait A { }
trait B { }
class User {
use A, B; // 多个
}在需要使用Trait的类里可以use多个Trait,中间用英文“,”隔开,例如:use A, B;
2、interface是接口,制定规则,只定方法名,不写方法体,只有规定没有实现。
a、只定义方法,不写具体的方法体。
b、在使用接口的类里必须实现接口中定义的所有方法。
c、一个类可以实现多个接口。
d、最适合强制规范,统一标准。
关于一个类可以实现多个接口的说明:
即一个类可以implements多个接口,比如:
class User implements 接口1, 接口2, 接口3 {
// 必须实现所有接口里的所有方法
}再比如:
// 接口1:必须能吃饭
interface Eat {
public function eat();
}
// 接口2:必须能睡觉
interface Sleep {
public function sleep();
}
// 接口3:必须能工作
interface Work {
public function work();
}然后在类里实现:
// 这个类要同时遵守 3 套规矩
class User implements Eat, Sleep, Work
{
// 实现 Eat 接口的方法
public function eat()
{
echo "吃饭\n";
}
// 实现 Sleep 接口的方法
public function sleep()
{
echo "睡觉\n";
}
// 实现 Work 接口的方法
public function work()
{
echo "工作\n";
}
}实例化并使用:
$user = new User();
$user->eat();
$user->sleep();
$user->work();
3、abstract class是抽象类,半实现半规定,能写普通方法、抽象方法、属性,能继承,单继承。
a、在接口里可以写普通方法、抽象方法和属性。
b、单继承,一个类里只能extends一个抽象类。
c、不能实例化,只能被继承。
d、最适合父类(抽象类)定义通用逻辑,子类扩展。在类用使用extends继承抽象类,例如:
abstract class BaseUser {
public function common() { }
abstract public function func();
}
class User extends BaseUser {
public function func() { }
}口诀和记忆:
怎么选择?(实战口诀)
1. 你需要复用代码 → 用 Trait
多个类有一样的方法,抽出来复用。
2. 你需要制定规范 / 强制实现方法 → 用 Interface
比如:必须实现 login ()、logout ()。
3. 你需要继承 + 共用属性 / 方法 → 用 抽象类
父类定义通用逻辑,子类差异化实现。最简单记忆法(必背)
Trait:我是搬运工,给你代码复用。
Interface:我是监工,只定规矩不干活。
Abstract:我是包工头,干一半,剩下让子类干。最终总结:
最终总结(极简版)
Trait:代码复用,多 use,有实现,无常量。
接口:制定规范,多实现,无实现、无属性。
抽象类:模板类,单继承,有属性、有实现。
页:
[1]