前言
本文利用Java中的多态特性来完成不同方式的支付功能。
案例:采用接口多态特性完成微信
、支付宝
、银联
的支付。
1 创建界面InterfaceHandler
(注意:这种方法只能作为演示,可以根据自己的需要进行改变,handler()
方法除外)
public interface InterfaceHandler { /** * 调用入口 */ void handler(); /** * 准备 */ void prepare(); /** * 开始 */ void begin(); /** * 结束 */ void end();}
perpare():这是我们付款前的准备工作。例如,我们需要先做
生成订单
,或者从数据库中读取支付的配置
可根据自身需要进行修改等操作。begin():这种方法是启动支付的功能流程,比如组装参数调用
微信API
返回支付接口prepay_id
等操作。end():这是调用微信支付后处理的逻辑。
handler():这种方法是我们整个支付程序的调用入口。
2 创建抽象类AbstractHandler
来实现InterfaceHandler
并重写界面handler
方法。
(注:一个类必须重写接口中的所有抽象方法才能实现某个接口,否则必须定义为抽象类。)
public abstract class AbstractHandler implements InterfaceHandler{ @Override public void handler() { //准备 prepare(); //开始 begin(); //结束 end(); }}
handler()方法作为我们整个支付程序的调用入口,控制我们的支付执行过程。
3 创建微信、支付宝、银联支付实现类,并继承AbstractHandler
(注:普通类继承抽象类后,必须重写抽象类中的所有抽象方法)
WechatPayService
、AlipayPayService
、UnionPayService
@Service("wechat-pay")public class WechatPayService extends AbstractHandler { @Override public void prepare() { System.err.println("准备微信支付参数!"); } @Override public void begin() { System.err.println("微信支付发起支付!"); } @Override public void end() { System.err.println("微信支付结束!"); }}@Service("alipay-pay")public class AlipayPayService extends AbstractHandler { @Override public void prepare() { System.err.println("准备支付宝支付参数!"); } @Override public void begin() { System.err.println("支付宝支付发起支付!"); } @Override public void end() { System.err.println("支付宝支付结束!"); }}@Service("union-pay")public class UnionPayService extends AbstractHandler { @Override public void prepare() { System.err.println("准备银联支付参数!"); } @Override public void begin() { System.err.println("银联支付发起支付!"); } @Override public void end() { System.err.println("银联支付结束!"); } @Override public void end() { System.err.println("银联支付结束了!"); }}
我们可以看到,我们的每一个支付实例都继承了AbstractHandler
抽象和重写方法,我们已经完成了整个过程的部署,但有一个问题是,当使用微信支付时,我们是否可以正确地调用微信的实例,而不是其他支付实例?
public class PayOrder { public static void main(String[] args) { InterfaceHandler wechatPayService = new WechatPayService(); wechatPayService.handler(); }}
准备微信支付参数!微信支付发起支付!微信支付结束!Process finished with exit code 0
这就是向上的转变。什么是向上的转变?向上转换是指向子类对象的父类引用。父类引用可以调用子类和父类的公共方法(如果子类重写父类方法,则调用子类方法)。
当对象实例化时,我们可以根据不同的需要实例化不同的对象。
进阶在第三步的三个实现类中,我们使用了这三个类@Service
并为他们设置了自定义的bean名称,这表明我们可以在IOC容器中获得这三个例子。
然后我们可以通过不同的Bean名获得不同的支付实例,执行每个实例handler()
实现微信支付功能的方法将实现微信实例。
@Service@AllArgsConstructorpublic class PayOrderImpl implements PayOrderService { private final Map<String, InterfaceHandler> interfaceHandlerMap; @Override public void pay() { InterfaceHandler handler = interfaceHandlerMap.get("wechat-pay"); handler.handler(); }}
在业务实现中,我们可以通过全球map获得不同的形式handler
实例,从而实现不同的支付渠道实施不同的支付方式。
