面试中经常会问到这个问题,那么我们到底应该怎么回答呢?
语法方面
首先,在java语言中,抽象类和接口在语法方面就是有一些区别的,总结整理如下:
相同点
- 都是位于较上层的抽象层.
- 都不能被实例化.
- 都可以只声明方法,不实现.
不同点
- 抽象类可以有不抽象的方法,即某个方法有默认的实现,而接口不可以.
- 使用抽象类使用extends关键字集成,而接口使用implement关键字来实现.
- 抽象类可以有构造器,接口不可以.
- 抽象类里的方法可以使用public,protected,default等修饰符,接口的只可以是public.
- 抽象类可以有main方法,接口不可以.
- 继承抽象类的类必须实现所有抽象方法,否则自身也是抽象类,接口的实现类必须实现所有抽象方法.
设计思想方面
上面语法方面的知识重要吗?重要,不了解的话你无法使用它们.
但是上面的不同点足以让我们来判断在某一个场景下该使用哪个吗?
我觉得不是,我觉得使用他他们最重要的是设计思想方面.
假如,现在要设计一个Door的类.我们通过两种方式都可以实现.
1 | //抽象类 |
这两种实现那种比较好一些?都还行,简单易懂.
那么这时候我们需要给门
添加报警功能,变成防盗门!怎么做呢?
1 | abstract class AbstractDoor { |
将上述代码改成这样吗?这样好吗?
细想一下,门是一个实体,门的抽象类里面应该有报警功能吗?
因此,我们其实应该做的是这样的.
1 | abstract class AbstractDoor { |
定义一个抽象类AbstractDoor,作为门
的基类,同时定义一个alarmable
的接口.(alarmable是我自己写的,我不知道有没有这个单词,大家懂就好).
定义了一个门的抽象类,所有的门都必须有这两个方法.(不能开关的叫什么门啊!),同时定义了一个可报警
的接口,当我们需要一个防盗门的时候,只需要继承AbstractDoor,同时实现Alarmable
的接口,这样就拥有了这三个方法.
同时,这样做的扩展性极好,当你发现门应该多一个共同的方法时,比如,锁住
,你可以在AbstractDoor
中扩展,当你需要一个可以报警的窗户的时候,你可以实现Alarmable
接口.岂不是美滋滋.
面试中如何回答我不敢给出正确答案,但是我认为,代码是写给人看的,所以你需要正确的设计以及正确的命名,来让代码的阅读者一看便懂,而不是深陷与语法,毕竟语法可以被创造.否则,我们需要抽象类和接口的区别干什么?直接将所有项目中用到的方法一股脑塞进一个类不就好了.
注意事项
本文的区别仅限于通俗意义上的区别.
另外,在java8中,Oracle已经开始尝试向接口中引入默认方法和静态方法,以此来减少抽象类和接口在语法上的差异。在java8之后,我们可以为接口提供默认实现的方法并且不用强制子类来实现它.有兴趣的胖友可以移步这里查看一哈.Java8 接口的静态方法和默认方法.
完。
ChangeLog
2018-11-18 完成以上皆为个人所思所得,如有错误欢迎评论区指正。
欢迎转载,烦请署名并保留原文链接。
更多学习笔记见个人博客——>呼延十