面试题:谈谈接口和抽象类有什么区别?

接口时对行为的抽象,它是抽象方法的集合,利用接口可以达到API定义和实现分离的目的。

接口不能实例化;不能包含任何非常量成员,任何field 都是隐含的 public static final 的意义;
同时,没有非静态方实现,也就是说要么是抽象方法,要么是静态方法。Java标准类库中,定义了非常多的接口,比如 java.util.List 。

抽象类 是不能实例化的类,用abstract 关键字修饰class,其目的主要是代码重用。除了不能实例化,形式上和一般的java 类并没有太大区别,可以有一个或多个抽象方法,也可以没有抽象方法。 抽象类大多用于抽取相关Java类的公用方法实现或者是共同成员变量,然后通过继承的方式达到代码复用的目的。`,Java 标准库中,比如Collection框架,很多通用部分被抽取成为抽象类,例如 java.util.AbstractList 。

Java 类实现interface 使用 implements 关键词,继承 abstract class 则是使用extends 关键字,我们可以参考 Java 标准库中的ArrayList。

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

在一些情况下存在特定场景,需要抽象出与具体实现、实例化无关的通用逻辑,或者纯调用关系的逻辑,但是使用传统的抽象类会陷入到单继承的窘境。以往常见的做法是,实现由
静态方法组成的工具类(Utils),比如java.util.Collections。

设想,为接口添加任何抽象方法,相应的所有实现了这个接口的类,也必须实现新增方法,否则会出现编译错误。对于抽象类,如果我们添加非抽象方法,其子类只会享受到能力扩展,而不用担心编译出问题。

接口的职责也不仅仅限于抽象方法的集合,其实有各种不同的实践。有一类没有任何方法的接口,通常叫作Marker Interface,顾名思义,它的目的就是为了声明某些东西,比如我
们熟知的Cloneable、Serializable等。这种用法,也存在于业界其他的Java产品代码中。

从表面看,这似乎和Annotation异曲同工,也确实如此,它的好处是简单直接。对于Annotation,因为可以指定参数和值,在表达能力上要更强大一些,所以更多人选择使
用Annotation。

Java 8增加了函数式编程的支持,所以又增加了一类定义,即所谓functional interface,简单说就是只有一个抽象方法的接口,通常建议使用@FunctionalInterface
Annotation来标记。Lambda表达式本身可以看作是一类functional interface,某种程度上这和面向对象可以算是两码事。我们熟知的Runnable、Callable之类,都
是functional interface,

还有一点可能让人感到意外,严格说,Java 8以后,接口也是可以有方法实现的!

从Java 8开始,interface增加了对default method的支持。Java 9以后,甚至可以定义private default method。Default method提供了一种二进制兼容的扩展已有接口的办法。比如,我们熟知的java.util.Collection,它是collection体系的root interface,在Java 8中添加了一系列default method,主要是增加Lambda、Stream相关的功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

半夏_2021

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值