1. 接口的基本语法和使用场景
1.1 接口可以突破PHP类的继承限制, 允许多继承, 形成了多层级的接口
Demo: 使用接口实现多继承
// 接口1
interface Itf1
{
public function func1();
public static function func2();
}
// 接口2
interface Itf2
{
public const CONST1 = '我是接口声明的常量';
}
// 实现类
/* 多继承 */
class Demo1 implements Itf1, Itf2
{
public function func1()
{
return '我是' . __METHOD__;
}
public static function func2()
{
return '我是' . __METHOD__;
}
public static function getConst()
{
return self::CONST1;
}
}
// 客户端调用
/* 获取接口常量 */
echobr(Demo1::getConst());
/* 调用接口声明的方法 */
echobr((new Demo1)->func1());
echobr(Demo1::func2());
/*
result:
我是接口声明的常量
我是Demo1::func1
我是Demo1::func2
*/
1.2 接口继承, 使用extends
关键字, 接口定义时, 可以继承多个其他接口
/** Demo2: 定义接口时, 继承另外的接口 */
interface Itf3 extends Itf1, Itf2
{
// 啥也不做, 就继承Itf1和Itf2两个接口
}
// 实现类
class Demo2 implements Itf3
{
public function func1()
{
return '我是' . __METHOD__;
}
public static function func2()
{
return '我是' . __METHOD__;
}
public static function getConst()
{
return self::CONST1;
}
}
// 客户端调用
/* 获取接口常量 */
echobr(Demo2::getConst());
/* 调用接口声明的方法 */
echobr((new Demo2)->func1());
echobr(Demo2::func2());
/*
result:
我是接口声明的常量
我是Demo2::func1
我是Demo2::func2
*/
1.3 使用抽象类可以实现接口的部分抽象方法
/** Demo3: */
// 抽象类
abstract class AbsDemo implements Itf3
{
/* 只实现func1方法 */
public function func1()
{
return '我是' . __METHOD__;
}
/* func2方法留着由实现类来实现 */
abstract public static function func2();
}
// 实现类
class Demo3 extends AbsDemo
{
public static function func2()
{
return __METHOD__ . '方法, 由' . __CLASS__ . '实现';
}
}
// 客户端调用
/* 获取接口常量 */
echobr(Demo3::CONST1);
/* 调用接口声明的方法 */
echobr((new Demo3)->func1());
echobr(Demo3::func2());
/*
result:
我是接口声明的常量
我是AbsDemo::func1
Demo3::func2方法, 由Demo3实现
*/
1.4 接口允许的成员有: 抽象方法, 常量, 构造方法(魔术方法的一种)
// Demo4: 接口允许的成员
interface Itf4
{
// 1. 常量
public const CONST1 = '我是接口声明的常量';
// 2. 抽象方法
/* 普通抽象方法 */
public function func1();
/* 静态抽象方法 */
public static function func2();
// 3. 构造方法
public function _construct();
}
2. trait的基本语法与使用场景
2.1 trait的基本语法
- 使用
trait
关键字定义trait - trait允许的成员有: 普通属性, 普通方法, 静态属性, 静态方法, 普通抽象成员, 普通抽象方法, 静态抽象属性, 静态抽象方法等. 不能在trait中定义常量.
/** Demo1: 定义trait, trait允许的成员 */
trait Trait1
{
// 普通成员
/* 使用trait的类中不能有同名属性, 所以一般不在trait中 */
public $username = 'zhangsan';
public function func1()
{
return '我是一个普通的方法';
}
// 静态成员
public static $message = '有内奸, 终止交易';
public static function func2()
{
return '我是一个静态方法';
}
// 抽象成员
/* 普通抽象成员 */
public $param;
abstract public function func3();
/* 静态抽象成员 */
public static $staticParam;
abstract public static function func4();
}
2.1 trait基本使用场景: 实现代码复用
// 打招呼的trait
trait Trait2
{
public static function sayHi()
{
return '你好, 我是' . __CLASS__;
}
}
// 使用trait的类
class Demo4
{
// 使用trait, 相当于把trait中定义的成员复制粘贴到使用类中
use Trait2;
}
// 客户端调用
echobr(Demo4::sayHi());
/*
result:
你好, 我是Demo4
*/
3. 学习心得
- 接口规定了一类事物应有的行为, 但并不提供这些行为的实现. 在实际使用中, 会把接口作为方法的参数, 方法在使用接口的方法时, 可以不关心接口的具体实现. 如:数据库操作, 只需知道调用接口的SQL处理方法, 就能返回什么样的数据即可. 而数据库操作的实现, 连接数据库的方式, 甚至使用什么数据库, 是可以暂时不关注的.
- trait提供了一种比类库的概念小的工具集合, 它也能实现代码的复用. 除开不能定义常量属性外, 其他成员类型均可在trait中定义. 可以把trait看作是不能实例化的普通类, 或是以use方式引入的抽象类.