类是描述一个实体的,实体则包含属性和该属性可以实现的动作,所以抽象类可以包含属性和方法。
接口是描述行为的,所以接口仅可以定义方法,不可以定义属性,但可以定义常量。
举例说明实现支付,支付可以有很多种方式:微信、支付宝、京东白条等。他们都至少有一个支付行为,所以首先定义一个支付接口。
<?php
interface PayInterface
{
//支付行为
public function pay();
}
它们都含有一些公有属性,比如支付时间、支付金额,流水号,以及设置和获得这些属性的方法。所以首先应该定义一个抽象类。
<?php
abstract class AbstractPay
{
private $pay_time;
private $amount;
private $serial_num;
abstract public function pay();
public function setPayTime($time)
{
$this->pay_time = $time;
}
public function setAmount($amount)
{
$this->amount = $amount;
}
public function setSerial($serial_num)
{
$this->serial_num = $serial_num;
}
public function getPayTime()
{
return $this->pay_time;
}
public function getAmount()
{
return $this->amount;
}
public function getSerial()
{
return $this->serial_num;
}
}
此时,三种支付方式分别单独定义一个类,继承抽象类、实现接口。(剩下需要的功能可以在里边自己定义)
<?php
include './PayInterface.php';
include './AbstractPay.php';
class WxPay extends AbstractPay implements PayInterface
{
public function pay()
{
echo 'This is wx pay method';
}
}
<?php
include './PayInterface.php';
include './AbstractPay.php';
class AliPay extends AbstractPay implements PayInterface
{
public function pay()
{
echo 'This is ali pay method';
}
}
<?php
include './PayInterface.php';
include './AbstractPay.php';
class JdPay extends AbstractPay implements PayInterface
{
public function pay()
{
echo 'This is jd pay method';
}
}
还需要定义一个工厂类,用静态方法根据参数实例化相应的支付类。
<?php
class PayFactory
{
static public function getPayMethod($method)
{
$class_name = ucfirst($method . 'Pay');
include ($class_name . '.php');
return new $class_name();
}
}
下面进行测试:
<?php
include_once ('./PayFactory.php');
$wx_obj = PayFactory::getPayMethod('wx');
echo $wx_obj->pay();
echo "\n";
echo $wx_obj->setPayTime(date('Ymd H:i:s', time()));
echo $wx_obj->setAmount('99.9');
echo $wx_obj->setSerial('AX3J6S8HYL');
echo $wx_obj->getPayTime();
echo "\n";
echo $wx_obj->getAmount();
echo "\n";
echo $wx_obj->getSerial();
echo "\n";