接口 & 抽象类

一、接口和抽象类

接口:用来封装代码,告诉外界提供了哪些功能(方法抽象),对行为的抽象。

  • 接口就是一种特殊的abstract class,但是比abstract class更加抽象

  • 在接口中声明方法,实现类实现接口—— 接口中方法不能在接口中实现,它需要一个实现类来实现它(通过具体的实现类来实例化:实现类 a = new 实现类() )

抽象类:用来把同一类事物抽象为一个类(代码复用),对本质上相同的行为、属性的抽象。

  • 抽象类实现接口时,可以完全覆盖/重写 接口中的方法,也可以只重写接口中的某几个方法



接口

抽象类

定义

Interface

abstract class

 

设计理念

行为的抽象

作用是降低耦合,对行为进行约束

对具体事物的抽象,包括属性、行为

作用是复用,即复用逻辑相同的代码

 

构成

方法:抽象方法(隐式默认 public abstract)

常量:默认 public static final

方法:抽象方法、普通方法

变量:成员变量

常量:默认 public static final

接口只包含抽象方法

抽象类可以包含抽象方法、非抽象方法

访问修饰符

接口方法默认都是public,不能有其他修饰符。

抽象方法可以有public、protected和default修饰符

 

继承/实现

接口extends多接口

抽象类implements多接口

子类implements多接口

抽象类extends单抽象类

子类extends单抽象类

接口:子类使用implements来实现接口。需要提供接口中所有方法的实现。

抽象类:子类使用extends来继承抽象类。如果子类不是抽象类,需要提供抽象类中所有抽象方法的实现。

接口的设计目的,是对类的行为进行约束(更准确的说是一种“有”约束,因为接口不能规定类不可以有什么行为),也就是提供一种机制,可以强制要求不同的类具有相同的行为。它只约束了行为的有无,但不对如何实现行为进行限制。对“接口为何是约束”的理解,我觉得配合泛型食用效果更佳。

而抽象类的设计目的,是代码复用。当不同的类具有某些相同的行为(记为行为集合A),且其中一部分行为的实现方式一致时(A的非真子集,记为B),可以让这些类都派生于一个抽象类。在这个抽象类中实现了B,避免让所有的子类来实现B,这就达到了代码复用的目的。而A减B的部分,留给各个子类自己实现。正是因为A-B在这里没有实现,所以抽象类不允许实例化出来(否则当调用到A-B时,无法执行)。
链接:https://www.zhihu.com/question/20149818/answer/150169365

资料:https://www.jianshu.com/p/c4f023d02f0c

二、使用

2.1 使用选择

首先看是对方法抽象,还是对方法+属性的抽象

其次看是否需要实现一些通用方法

综合以上来考虑使用接口还是抽象类

2.2 两者结合使用

接口 <--- 抽象类 <--- 实现类

  • 接口:定义方法

  • 抽象类:实现部分方法(确定且重复的);添加新的方法

  • 实现类:实现剩余的方法

即,在业务比较复杂时,开始先抽象出未实现的接口,然后把确定且重复的接口实现在抽象类中,最后在一个或多个子类(一般有多个子类)中实现未实现的接口方法。这样做有两个好处:1,抽象分层,逻辑清晰;2,多人合作中分工明确,每个人负责的业务子类只需要实现自己的接口就好,重复的就直接调用抽象类已实现的。Java源码中最明显得例子就是HashMap先继承抽象类AbstractMap,AbstractMap是实现了Map接口的抽象类。

 2.3 如何获取并使用某个实现类

1、直接使用(单实现类)

    @Autowired
    private ResultRepositoryService resultRepository;

2、@Qualifier显示指定bean名称(多实现类)

    @Autowired
    @Qualifier("paramVerifyServiceImpl")
    private IParamVerifyService paramVerifyService;

3、applicationContext.getBean(beanName)

复制代码
@Component
public class SpringBeanUtils implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * 根据bean唯一标识获取实例
     *
     * @param beanName bean的名称标识
     * @param <T>      实例类型
     * @return 实例
     */
    public static <T> T getBean(String beanName) {
        return (T) applicationContext.getBean(beanName);
    }
}
复制代码

 

posted @   zhegeMaw  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示