原标题:我是如何理解Java抽象类和接口的

在面试中我们经常被问到:Java中抽象类和接口的区别是什么?

然后,我们就大说一通抽象类可以有方法,接口不能有实际的方法啦;一个类只能继承一个抽象类,却可以继承多个接口啦,balabala一大堆,就好像把标准答案熟练的说出来一样。

抽象类和接口这篇文章讲到了他们的区别和联系,它们确实有很多相似的地方,但是从本质上看,或从语言的设计角度来看,这不是它们最本质的区别。

不卖关子,我个人对这两个的理解:

类是具体实例的抽象,比如一个json字符串的抽象;而抽象类就是类的抽象;接口就是抽象类的抽象,接口更像是一种协议

听我慢慢道来~

吐槽

首先,我必须吐槽一下这种面试,我认为面试官凡事问出这种类似“说说抽象类和接口的区别”,“说说进程和线程的区别”等等问题,都是不负责的表现。

为什么呢?

一个原因就是,面试官对想要招的人完全没有自己的评价标准,另一个原因就是对面试者不负责。这种问题根本不能考验面试者的水平。

那么,如果我来面试别人,我会问:请你说说你怎么理解抽象类和接口;如果要你向你外婆解释进程和线程的区别,你会怎么解释?

我觉得这可以考验面试者对问题的理解程度,我想微软的面试题(你如何向你奶奶解释Excel)一样,考验一个人对某一事物的理解程度(虽然,至今我还不能很好的想明白这个问题 -。-)

抽象类和接口的区别

说到抽象类和接口,就必须要说到类。

一个类就是对现实事物的抽象。

比如定义一个BenzCar类,就需要对现实的奔驰汽车有很好的抽象(当然奔驰汽车有好多系列,这里不钻牛角尖)。也就是说如果你要造一辆奔驰汽车,就需要BenzCar这个类(这辆奔驰汽车就是内存中的一个Instance)。

那么抽象类就是对类的抽象。

怎么理解呢?就是说有很多汽车厂商一起定义一种规范(Car类),说要造一辆汽车就需要有发动机,轮胎,音响设备…(这些就相当于抽象方法),具体用什么发动机,轮胎,音响设备由每个汽车厂商自己去完成。这样就有各种汽车了,奔驰牌的,宝马牌的,丰田牌的…

接口就是对抽象类的抽象

这只是我个人的理解。

在我们日常生活中可以看到各种“接口”,电源插座就是一种。开始我是看到耗子叔的博客在开始理解“控制翻转”这个概念的——IoC/DIP其实是一种管理思想| 酷壳- CoolShell.cn。后来我就想,这个东西其实无处不在,制造电源插座的厂和制造电器的厂只要约定一种“接口”——两口插座或三口插座,当然每个国家的接口都不一样,不同接口之间的转换就需要用适配器了。

其实程序中也一样,比如所有的交通工具可以抽象为一个接口Drivable(可能由于经验原因,我考虑的不是很完善),表示实现这个接口的类创建的对象(比如:汽车,飞机,轮船等等)都是可以驾驶的

publicinterfaceDrivable{ publicvoiddrive();}

然后,我们就可以创建一个AbstractCar类,表示这个对所有汽车类的一个抽象,所有可以驾驶的汽车都必须继承这个类,这个抽象类中规定了一些抽象方法,比如getEngine()方法,这说明每种汽车的引擎都不太一样,需要在子类中自定义(当然,你也可以继承AbstractCar类,对所有可能具有相同引擎的汽车进行一层抽象)。

为什么对Drivable的drive()方法进行了默认实现,但是默认实现中却直接抛出了异常呢?

其实这是一种实现接口的方法,还有一种方法就是将drive()设为abstract。这两种实现方式,我觉得从功能上讲是一样的,但是从类设计上讲是不同的。

下面代码中的实现,我是参考了java.util.AbstractList中add(int location, E object)方法的设计,它的文档中写到:

* @throws UnsupportedOperationException * ifadding to thisList isnotsupported. publicabstractclassAbstractCarimplementsDrivable{ publicabstractEngine getEngine(); publicabstractWheel getWheel(); @Overridepublicvoiddrive(){ thrownewUnsupportedOperationException(); } // 省略其他方法和属性}

那么上面这段代码中的drive()可以理解为:

默认情况下“汽车”是不能开的,你实现了一个汽车类后,需要Override这个方法,实现自己的drive方法以java容器中的List举例

到源码里面找,你就会发现List的继承关系最顶层的就是Iterable,就表示说List是可以遍历的,而且它还会产生一个Iterator接口对象。这表示一个列表可以通过这个迭代器来遍历。

这就像上面说的,所有的交通工具都是可以驾驶的一样,所有的列表都是可以遍历的。

一层一层往下,类就变得更加具体。

最后

为什么接口可以继承?

其实这个原理很简单。因为总有一个最本质的协议来约束大家,比如所有的交通工具都是可以驾驶的,所有的容易都是可以遍历的。然后协议会渐渐变得更加具体:

Iterable

从下往上看,就是一层比一层抽象。

就像我在文章开头说的,

你用ArrayList类可以创建很多个对象,ArrayList就是这些对象的一次抽象

而AbstractList是对ArratList的一次抽象,你用AbstractList可以创建ArrayList,也可以创建Stack,或LinkedList等

List接口就是对所有的列表类的抽象

Collection就是对所有单一元素的容器的抽象

Iterable就是一个最高层次的抽象了,表示所有的容器都是可以遍历的

注:

应该有很多我考虑不周全的地方,欢迎大家指正并且讨论返回搜狐,查看更多

责任编辑:

如何理解java抽象类,我是如何理解Java抽象类和接口的相关推荐

  1. 超硬核的Java工程师分享,什么是Java?为什么我要做Java,我是如何学习Java的?

    Java是啥 新手程序员通常会走入一个误区,就是认为学习了一门语言,就可以称为是某某语言工程师了.但事实上真的是这样吗?其实并非如此. 今天我们就来聊一聊,Java 开发工程师到底开发的是什么东西.准 ...

  2. sqlsever主库从库如何切换_超硬核的Java工程师分享,什么是Java?为什么我要做Java,我是如何学习Java的?...

    Java是啥 新手程序员通常会走入一个误区,就是认为学习了一门语言,就可以称为是某某语言工程师了.但事实上真的是这样吗?其实并非如此. 今天我们就来聊一聊,Java 开发工程师到底开发的是什么东西.准 ...

  3. java 接口是抽象类吗_我是如何理解Java抽象类和接口的

    在面试中我们经常被问到:Java中抽象类和接口的区别是什么?然后,我们就大说一通抽象类可以有方法,接口不能有实际的方法啦;一个类只能继承一个抽象类,却可以继承多个接口啦,balabala一大堆,就好像 ...

  4. java抽象和接口的理解_Java接口实现与抽象类的区别理解 | 彬菌

    版权声明:转载原创文章请以超链接形式请注明原文章出处,尊重作者,尊重原创! 恰饭广告 接口:接口是抽象方法的集合.接口通常以interface来声明. 接口注意事项: 1.严格来说,接口是用来实现(i ...

  5. java画板抽象类_深入理解Java抽象类与接口

    基于抽象类与接口有太多相似之处且均体现着oop的抽象性,本文从以下几点谈谈对这两者的理解. 1.抽象类 2.接口 3.各自优缺点以及应用举例. 1.抽象类 在了解抽象类之前,先来了解一下抽象方法.抽象 ...

  6. java请编写公共类继承抽象类_(Java相关)怎么理解抽象类,继承和接口?

    著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 作者:海子 来源:博客园 一.抽象类 在了解抽象类之前,先来了解一下抽象方法.抽象方法是一种特殊的方法:它只有声明,而没有具体的 ...

  7. java 虚基类_C++中虚基类与抽象类的简单理解。

    虚基类   是相对于它的派生类而言的,它本身可以是一个普通的类. 只有它的派生类虚继承它的时候,它才称作虚基类,如果没有虚继承的话,就称为基类.比如类B虚继承于类A,那类A就称作类B的虚基类,如果没有 ...

  8. 对java支持并发的理解_Java并发知识(1)

    1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用.而线程是在进程中执行的一个任务.Java运行环境是一个包含了不同的类和 ...

  9. 深入理解java虚拟机_深入理解Java类加载

    本文目的: 深入理解Java类加载机制; 理解各个类加载器特别是线程上下文加载器; Java虚拟机类加载机制 虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行校验.转换解析和初始化,最 ...

  10. 沉淀再出发:关于java中的AQS理解

    沉淀再出发:关于java中的AQS理解 一.前言 在java中有很多锁结构都继承自AQS(AbstractQueuedSynchronizer)这个抽象类如果我们仔细了解可以发现AQS的作用是非常大的 ...

最新文章

  1. 一个妹子图应用客户端源码
  2. nvm 装 nodejs 重启终端失效的解决方法
  3. 新CCIE笔记之'口口相传'路由协议
  4. 【PM模块】操作功能概览
  5. 网易云信SDK V3.2.0版发布啦!
  6. Hibernate陷阱
  7. android preferenceActivity的用法
  8. java做登录时要加锁吗_你用对锁了吗?谈谈 Java “锁” 事
  9. 如何提高FPGA的工作频率
  10. Windows10系统安装详细教程
  11. 知识图谱之WordNet
  12. 最大子矩阵和POJ1050
  13. 2019pro与air怎么选_新款 MacBook Air 和入门级 MacBook Pro 如何选?看完这篇就知道了...
  14. linux下使用打印机
  15. 第一部android手机,安卓手机诞生十年,第一部Android 一.零手机长这样
  16. 初学者LDPC码扫盲
  17. 【夏目鬼鬼分享】StringBoot整合RabbitMQ,使用Direct、Fanout、Topic三种模式
  18. 整理几个国内外常用的广告联盟给大家参考
  19. 钢管直线度重要性 在线直线度测量仪保证质量
  20. html动态网页作品,HTML5与CSS3实现动态网页

热门文章

  1. SignalR主动通知订阅者示例
  2. JVM java虚拟机
  3. 找到你真正喜欢做的事情,坚持下去,坚持多深入一些(转)
  4. 意外收获——我与FPGA的第一次
  5. 广州仙村中学2021高考成绩查询,仙村中学(增城区)
  6. 使用 SDK (Nodejs)操作阿里 OSS (对象存储服务)学习笔记
  7. css设置table阴影浮动效果
  8. [Matlab]中pcolor和colormap的使用
  9. python三引号的作用_Python学习笔记(三)基本数据类型
  10. CentOS:bash: g++: 未找到命令...