首页 > 编程知识 正文

什么是抽象类,什么是接口,它们有什么不同?,抽象类和接口的不同之处

时间:2023-05-03 06:28:03 阅读:191376 作者:756

代码大全一书中说到,软件开发的本质上就是:对复杂度的控制管理。

开发过程中,我认为最大的复杂度来自“变化”,项目需求的变化,项目架构的变化,功能具体实现的变化等等。

而抽象类和接口正是我们工作中常用的用以解决具体实现变化的一种方式,它为我们提供了:“将接口和实现分离的方法”。这样,我们编码过程就可以面向接口而不是面向实现编程,这样当具体实现发生变化时,上游系统将基本不用做改动。

抽象类和接口本质上的目的都是一样的:“提供更加高度的抽象”。但是,接口相对于抽象类,它的抽象程度更进一步。

下面,我将从:(1):  语言语法   

                         (2):  设计理念

两个层面对两者的差异,阐述下自己的见解。我认为,两者更加重要的差异是设计层面的差异,也是两者最本质的差异。

 

一:语言语法差异

两者的语法差异是大家比较熟知的差异,网上比比皆是,下面进行具体的阐述。

1. 方法

抽象类可以提供方法的具体实现,而JDK1.8之前的接口方法都默认是 public abstract的。但是JDK1.8之后,接口方法可以有static方法和通过default关键字提供默认方法实现了。

实现类可以直接通过接口类名访问接口的static方法,通过接口实现类的对象访问其默认方法,或者实现类对接口默认方法进行覆写。当类实现多个接口,超过2(含)个接口有一样签名的方法时,实现类就必须对相应的默认方法进行覆写,不然编译器无法识别调用的是哪个方法。

2. 属性

抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的。

3. 构造方法

抽象类和实现类是继承的关系,而且它的普通属性也有初始化的需求,所以抽象类是有构造方法的,而且如果有子类继承,它则必须具备无参的构造方法。而接口是更加纯粹的抽象,它是不具备构造方法的。通过看javap –verbose 命令看具体的字节码,是可以清楚的看到,接口是没构造方法的,而抽象类是有的,这里就不演示了。

但是,抽象类构造方法仅仅是为了继承和初始化的需要,是不能用于实例化一个抽象类的对象。这也是合常理的,抽象的事物是没有真实存在的个体的。

但是,大家可能回想,既然抽象类有public 权限的构造方法,为什么不能实例化?这是因为,当我们实例化一个普通对象时,jvm是通过new这条指令来完成的,当类名的符号解析最后被解析到了抽象类或者接口的时候,new 指令将抛出 InstantiationError 异常,所以,抽象类是无法实例化的。

4. 多重继承

单继承限制实现类只能继承一个抽象类,而接口可以实现多个接口。

下面的示例代码,对上述JDK1.8接口新特性作了进一步的说明。

public interface Test {   static void staticMethod() {       System.out.println("staticMethod");   }   default void defaultMethod() {       System.out.println("defaultMethod");   }}class A implements Test {   public static void main(String[] args) {       Test.staticMethod();       new A().defaultMethod();   }}class B implements Test {   @Override   public void defaultMethod() {       System.out.println("defaultMethod in B");   }   public static void main(String[] args) {       Test.staticMethod();       new B().defaultMethod();   }}

                                                               代码1: jdk1.8 接口新特性示例

 

二:设计理念差异

我个人认为,设计理念的差异是两者最本质的差异,语法层面的那些差异也是设计理念的具体表现形式而已。

正是这些理念的差异,才出现了上述看似奇怪,其实很合理的语法规则。深刻理解设计理念层面的差异,会帮助你理解语法层面的差异,而不是强行记住它。

1. 抽象类

大家想想,自己平时工作中,抽象类使用的最多的场景是什么?

就我个人而言,一般是这样的:A,B,C 三个类貌似差不多啊,有很多公共的属性或者方法,于是我,抽象出一个抽象类D,将这些公共的部分放到抽象类中,然后ABC三个类继承自这个抽象类D。

所以,抽象类是“自下而上”的设计,它在完成ABC三个下层的类后,发现需要抽象一个上层的抽象类D,所以说它是 自下而上的设计。

抽象类是很有用的重构工具,它将继承层次结构上移,这种上移操作一般是后发的。

抽象类是对一类事物的抽象,类ABC和抽象类D一般具备“is-a”的关系。它通过继承操作实现它的终极目标:复用。

所以,抽象类是能拥有普通属性和普通方法的,它除了不能实例化和必须有抽象方法外,和普通类没太大区别。

2. 接口

接口则不一样,它是“自上而下”的设计理念,我们工作的设计过程中,一般都是先设计好接口,先不考虑具体的实现。

所以,如果说抽象类是对事物的抽象,接口就是对行为的抽象,实现了接口的类符合“like-a”的关系,接口建立了类和类之前的契约和协议,这也是它的终极目标:行为契约。

接口将接口和具体实现两者解耦的更加彻底,使得面向接口编程更加的容易和纯粹。

三:总结

相信通过上面两个方面的阐述,大家对抽象类和接口有了更加深刻的认识。

所以,对于两者应该使用哪个的问题,我们结合设计思路和具体的编码需要就能快速的作出选择。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。