abstract 抽象类与接口类(PHP)
abstract 抽象类(PHP)
作用
- 约束子类必须实现指定方法:抽象方法只有声明、没有实现,子类继承后必须重写这个抽象方法,否则子类也得标记为
abstract,不能实例化。用来统一接口规范。 - 可以放通用共用代码:和接口
interface不一样,抽象类里面可以写已经实现好的普通方法、属性,子类直接复用。 - 本身不能 new 实例,只能被继承,用来做基类、模板骨架(模板方法模式非常常用)。
对比一句话:
interface:全部都是契约,不能写实现,一个类可以多实现abstract class:一半契约(abstract方法)+一半现成代码,只能单继承
写法规则(PHP)
- 类前面加
abstract - 抽象方法:前面
abstract,没有函数体,以分号结尾,不能有{} - 普通方法、属性、常量正常写,随便写实现
- 子类
extends抽象类,必须全部实现父类所有抽象方法 - 抽象类不能
new
最简示例
<?php
abstract class CarrierBase
{
// 抽象方法:子类必须实现
abstract public function sendOrder(array $orderData): bool;
abstract public function cancelOrder(int $orderId): bool;
// 已经实现的公共方法,子类直接继承复用
protected function log(string $msg): void
{
echo date('Y-m-d H:i:s') . ' ' . $msg . PHP_EOL;
}
}
// 子类实现抽象类
class SelfCourierCarrier extends CarrierBase
{
public function sendOrder(array $orderData): bool
{
$this->log('自有骑手接单:' . $orderData['id']);
return true;
}
public function cancelOrder(int $orderId): bool
{
$this->log('自有骑手取消订单:' . $orderId);
return true;
}
}
// $base = new CarrierBase(); // 报错!抽象类不能实例化
$carrier = new SelfCourierCarrier();
$carrier->sendOrder(['id' => 1001]);结合你上面跑腿运力场景的例子(贴合你的 CarrierInterface)
你现在是 CarrierInterface 接口;如果很多运力都共用一套日志、组装请求的逻辑,就适合改成抽象基类:
abstract class AbstractCarrier implements CarrierInterface
{
// 公共通用能力,所有运力复用
protected function buildOrderParam(array $raw): array
{
return [
'order_no' => $raw['order_sn'],
'addr_from' => $raw['from_address'],
'addr_to' => $raw['to_address'],
];
}
}
class SelfCourierCarrier extends AbstractCarrier
{
public function dispatch(array $order): bool
{
$param = $this->buildOrderParam($order);
// 自有骑手分发逻辑
return true;
}
}
class ThirdPartyCarrier extends AbstractCarrier
{
public function dispatch(array $order): bool
{
$param = $this->buildOrderParam($order);
// 调用UU/闪送接口
return true;
}
}重点坑点
- 抽象方法不能写body:
abstract public func();✅,带大括号 ❌ - 子类实现的方法,访问权限不能比父抽象方法更严格(父public,子类不能改成protected/private)
- 抽象类可以没有任何抽象方法(可以,但意义不大,仅用来禁止直接new基类)
- 一个类只能继承一个抽象类(PHP单继承)
什么时候选 abstract,什么时候选 interface
- 多个子类有大量重复共用代码 → abstract 抽象类
- 只定义调用契约、没有公共逻辑、一个类需要多套契约 → interface
版权属于:Joyber
本文链接:https://blog.qqvbc.com/default/1582.html
转载时须注明出处及本声明