抽象类实现接口的意义

文章目录


前言

抽象类和接口其实都是抽象的一种,那么他俩有何异同呢?

抽象类实现接口的意义何在?


一、抽象类和接口对比

  1. 接口大家比较熟悉,它其实是一种规范,规定了方法的入参,反参等,一种抽象, 关键字是 interface;
  2. 抽象类是用 abstract 修饰的类,可以包含抽象方法,也可以不包含抽象方法,可以有普通方法
  3. 一般来说接口中的方法都是抽象的,无方法体的,但是java8之后,增加了default (大家课后了解下),它让接口也可以有方法体了,那么其实这里的default 就增强了接口的功能,不逊于抽象类了;
  4. 接口是用来实现的,而且实现一个接口的时候,子类必须实现接口中的所有方法
  5. 抽象类是用来被继承的,抽象类中的抽象方法可以在子类中选择性实现,这就是抽象类的灵活性
  6. 那么当我用抽象类实现接口,我可以选择某些方法我在抽象类中实现,某些方法我不实现,而是继续在抽象类的子类中实现,那么这个方法我虽然实现了,但是还是一个抽象方法(你以为我实现了,然后并没有)

没有代码,仅讲解的的博主相当于耍流氓,接下来进入代码环节

二、举例说明三种情况

1.接口实现类

使用场景: 我又两种支付方式,微信/支付宝, 为了统一对外逻辑,我弄成一个接口对外暴露,方便统一调用

接口

java 复制代码
public interface PayService {

    /**
     * 获取支付具体实现
     *
     * @return
     */
    String getType();

    /**
     * 具体支付方法
     *
     * @param order
     * @param money
     * @return
     */
    String toPay(String order, Integer money);
}

### 实现类
```java 
@Service
public class AliPayServiceImpl implements PayService {
    /**
     * 获取支付具体实现
     *
     * @return
     */
    @Override
    public String getType() {
        return "Ali";
    }

    /**
     * 具体支付方法
     *
     * @param order
     * @param money
     * @return
     */
    @Override
    public String toPay(String order, Integer money) {
        System.out.println("阿里支付用支付宝,优惠一元");
        return "Ali支付 订单号: " + order + " 金额: " + (money - 1);
    }
}

// =======================================================

@Service
public class WxPayServiceImpl implements PayService {
    /**
     * 获取支付具体实现
     *
     * @return
     */
    @Override
    public String getType() {
        return "Wx";
    }

    /**
     * 具体支付方法
     *
     * @param order
     * @param money
     * @return
     */
    @Override
    public String toPay(String order, Integer money) {
        System.out.println("微信支付,原价支付");
        return "Wx支付 订单号: " + order + " 金额: " + money;
    }
}

2.抽象类实现类

使用场景: 依然是第一个支付场景,我这里简单改造下;抽象类还能有普通方法,这里我增加一个支付打印

抽象类

java 复制代码
public abstract class PayService {

    /**
     * 获取支付具体实现
     *
     * @return
     */
    abstract String getType();

    /**
     * 具体支付方法
     *
     * @param order
     * @param money
     * @return
     */
    abstract String toPay(String order, Integer money);


    /**
     * 支付成功打印
     */
    public void sout(){
        System.out.println("我支付成功了");
    }
}

实现类(子类)

java 复制代码
@Service
public class AliPayServiceImpl extends PayService {
    /**
     * 获取支付具体实现
     *
     * @return
     */
    @Override
    public String getType() {
        return "Ali";
    }

    /**
     * 具体支付方法
     *
     * @param order
     * @param money
     * @return
     */
    @Override
    public String toPay(String order, Integer money) {
        System.out.println("阿里支付用支付宝,优惠一元");
        return "Ali支付 订单号: " + order + " 金额: " + (money - 1);
    }
}

// =========================================================
@Service
public class WxPayServiceImpl extends PayService {
    /**
     * 获取支付具体实现
     *
     * @return
     */
    @Override
    public String getType() {
        return "Wx";
    }

    /**
     * 具体支付方法
     *
     * @param order
     * @param money
     * @return
     */
    @Override
    public String toPay(String order, Integer money) {
        System.out.println("微信支付,原价支付");
        return "Wx支付 订单号: " + order + " 金额: " + money;
    }
}

这里看完是不是觉得抽象比接口强大,那为什么还要接口呢?

  • 接口可以解决多重继承问题,提供更灵活的扩展和维护
  • Java中的抽象类和接口各有其应用场景,抽象类和接口都可以定义规范,但实现规范的方式不同。抽象类是具体实现的规范,而接口是行为的规范。
  • 抽象类可以解决单继承局限,避免多继承带来的复杂性和低效性

3.抽象类实现接口

使用场景: 仍然是支付场景,接口中定义了四个方法 (abcd),有三个实现类 A B C ;

其中A 需要实现 ab d, B需要实现 bc d, C需要实现ca d

也就是A B C 三个实现类不需要实现接口中的所有方法,但是都需要实现d方法,而且是一个逻辑

这里d方法在每个子类中都实现一遍没必要,重复代码,咋办呢? 我们在接口和实现类之间加一个 抽象类

接口

java 复制代码
public interface PayService {

    /**
     * 获取支付具体实现
     *
     * @return
     */
    String getType();

    /**
     * 具体支付方法
     *
     * @param order
     * @param money
     * @return
     */
    String toPay(String order, Integer money);


    /**
     * 扣减库存
     * @param num 购买数量
     * @return
     */
    int decreaseStash(int num);

    /**
     * 打印成支付
     */
    void sout();

}

抽象类

java 复制代码
public abstract class PayAbstract implements PayService{

    /**
     * 获取支付具体实现
     *
     * @return
     */
    @Override
    public String getType() {
        return null;
    }

    /**
     * 具体支付方法
     *
     * @param order
     * @param money
     * @return
     */
    @Override
    public String toPay(String order, Integer money) {
        return null;
    }

    /**
     * 扣减库存
     *
     * @param num 购买数量
     * @return
     */
    @Override
    public int decreaseStash(int num) {
        return 0;
    }

    /**
     * 打印成支付
     */
    @Override
    public void sout() {
        System.out.println("支付成功");
    }
}

三个实现类

java 复制代码
@Service
public class AliPayServiceImpl extends PayAbstract {
    /**
     * 获取支付具体实现
     *
     * @return
     */
    @Override
    public String getType() {
        return "Ali";
    }

    /**
     * 具体支付方法
     *
     * @param order
     * @param money
     * @return
     */
    @Override
    public String toPay(String order, Integer money) {
        System.out.println("阿里支付用支付宝,优惠一元");
        return "Ali支付 订单号: " + order + " 金额: " + (money - 1);
    }
}

// ============================================================
@Service
public class WxPayServiceImpl extends PayAbstract {

    /**
     * 具体支付方法
     *
     * @param order
     * @param money
     * @return
     */
    @Override
    public String toPay(String order, Integer money) {
        System.out.println("微信支付,原价支付");
        return "Wx支付 订单号: " + order + " 金额: " + money;
    }

    /**
     * 扣减库存
     *
     * @param num 购买数量
     * @return
     */
    @Override
    public int decreaseStash(int num) {
        return num;
    }
}

// ============================================================

@Service
public class JUHEPayServiceImpl extends PayAbstract {

    /**
     * 获取支付具体实现
     *
     * @return
     */
    @Override
    public String getType() {
        return "JUHE";
    }

    /**
     * 扣减库存
     *
     * @param num 购买数量
     * @return
     */
    @Override
    public int decreaseStash(int num) {
        return num;
    }
}

这样在接口和抽象类之间又做了一层抽象,抽象层提取了公共的方法d (sout),而且让每个实现类都更加灵活的实现方法


总结

抽象类实现接口的意义在于提供了一种灵活且层次分明的代码结构,有助于实现模块化和可维护性。

具体来说,抽象类可以作为继承层次结构中的基础类,提供一些公共方法和属性,子类可以继承和扩展。而接口则定义了一组相关的方法规范,约束了实现这些方法的类或抽象类的行为。这有助于确保代码的模块化,提高代码的可重用性和可维护性。

抽象类相当于在原有抽象的基础上,再次抽象,提取了一些公共方法;

相关推荐
2401_857610035 分钟前
Spring Boot框架:电商系统的技术优势
java·spring boot·后端
希忘auto21 分钟前
详解MySQL安装
java·mysql
娅娅梨24 分钟前
C++ 错题本--not found for architecture x86_64 问题
开发语言·c++
汤米粥29 分钟前
小皮PHP连接数据库提示could not find driver
开发语言·php
冰淇淋烤布蕾32 分钟前
EasyExcel使用
java·开发语言·excel
拾荒的小海螺39 分钟前
JAVA:探索 EasyExcel 的技术指南
java·开发语言
秀儿还能再秀1 小时前
机器学习——简单线性回归、逻辑回归
笔记·python·学习·机器学习
Jakarta EE1 小时前
正确使用primefaces的process和update
java·primefaces·jakarta ee
马剑威(威哥爱编程)1 小时前
哇喔!20种单例模式的实现与变异总结
java·开发语言·单例模式
白-胖-子1 小时前
【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-统计数字
开发语言·c++·算法·蓝桥杯·等考·13级