接口和抽象类,傻傻分不清楚?



01、

来看网络上对接口的一番解释:

接口(英文:Interface),在 Java 编程语言中是一个抽象类型,是抽象方法的集合。一个类通过继承接口的方式,从而来继承接口的抽象方法。

兄弟们,你们怎么看,这段解释把我绕得晕乎乎的,好像喝过一斤二锅头。到底是解释抽象类呢还是接口呢?傻傻分不清楚。

搞不清楚要用抽象类还是接口,就先来看看两者之间的区别。来,抽象类和接口,你俩过来比比身高。

1.抽象类中的方法可以有方法体,能实现方法具体要实现的功能,但是接口中的方法不行,没有方法体。2.抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的,并且是隐式的,缺省的。3.接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法的。4.一个类只能继承一个抽象类,而一个类却可以实现多个接口。

02、

好像知道了两者之间的区别,但印象还是有些模糊。没关系,我们进一步深入。

抽象类

抽象类体现了数据抽象的思想(不然呢),是实现多态的一种机制。抽象类定义了一组抽象的方法,至于这组抽象方法的具体表现形式由子类来继承实现。

抽象类就是用来继承的,否则它就没有存在的任何意义。举个例子,我们来定义一个抽象的作者类。

abstract class Author {    abstract void write ();?    public void sleep () {        System.out.println("吃饭睡觉打豆豆");    }}

作为一名作者,本职工作就是搞写作的,其他时间就吃饭睡觉打豆豆;但至于能写出什么样的作品,就要看是哪一个作者了。比如说,沉默王二能写出的作品一定是幽默风趣的。

public class Wanger extends Author {?    @Override    void write() {        System.out.println("沉默王二的作品《Web 全栈开发进阶之路》,读起来轻松惬意");    }?}

注意到了没?抽象类是可以有自己的方法的,但继承它的子类可以忽视。

接口

接口是一种比抽象类更加抽象的“类”,毕竟是用关键字 interface 声明的,不是用 class

接口只是一种形式,就好像一纸契约,自身不能做任何事情。但只要某个类实现了这个接口,就必须按照这纸契约来办事:接口里提到的方法必须全部实现,少一个都不行(抽象类的子类可以忽视非抽象方法)。举个例子,我们来定义一个北航出版合同的接口。

interface ContractBeihang {    void scriptBeihang();}

一旦作者签订了合同,那么就必须定期完成一定量的书稿。

public class Wanger extends Author implements ContractBeihang {?    @Override    void write() {        System.out.println("作品《Web 全栈开发进阶之路》,读起来轻松惬意的技术书");    }?    @Override    public void scriptBeihang() {        System.out.println("一年内完成书稿啊,不然要交违约金的哦。");    }?}

接口是抽象类的补充,Java 为了保证数据的安全性不允许多重继承,也就是说一个类同时只允许继承一个父类(为什么呢?请搜索关键字“菱形问题”)。

但是接口不同,一个类可以同时实现多个接口,这些接口之间可以没有多大的关系(弥补了抽象类不能多重继承的缺陷)。比如说,沉默王二不仅签了北航出版社的合同,还和 51CTO 签了付费课程的合同。

public class Wanger extends Author implements ContractBeihang, Contract51 {?    @Override    void write() {        System.out.println("作品《Web 全栈开发进阶之路》,读起来轻松惬意的技术书");    }?    @Override    public void scriptBeihang() {        System.out.println("一年内完成书稿啊,不然要交违约金的哦。");    }?    @Override    public void script51() {        System.out.println("王老师,先把 Java 云盘的大纲整理出来。");    }?}

03、

通过上面举的例子,是不是对接口和抽象类有比较清晰的认知了?如果还没有,来来来,我们再来比较一下接口和抽象类之间的差别。

究竟什么时候使用接口,什么时候使用抽象类呢?

1、抽象类表示了一种“is-a”的关系,而接口表示的是“like-a”的关系。也就是说,如果 B 类是 A(沉默王二是一个作者),则 A 应该用抽象类。如果 B 类只是和 A 有某种关系,则 A 应该用接口。

2、 如果要拥有自己的成员变量和非抽象方法,则用抽象类。接口只能存在静态的不可变的成员变量(不过一般都不在接口中定义成员变量)。

3、为接口添加任何方法(抽象的),相应的所有实现了这个接口的类,也必须实现新增的方法,否则会出现编译错误。对于抽象类,如果添加了非抽象方法,其子类却可以坐享其成,完全不必担心编译会出问题。

4、抽象类和接口有很大的相似性,请谨慎判断。Java 从1.8版本开始,尝试向接口中引入了默认方法和静态方法,以此来减少抽象类和接口之间的差异。换句话说,两者之间越来越难区分了。

04、

在实际的开发应用当中,抽象类我用得不多(这可真是大实话);接口我倒是用得蛮多的,就像下面这样子:

public interface CityMapper {?    @Select("select * from city")    List<City> getCitys();?}

@Insert@Update@Delete@Select 被称为 Mybatis 的注射器注解。

是不是突然感觉有点懵?之前还在谈接口和抽象类,怎么一下子跳跃到 Mybatis 上面了呢?还有什么映射器注解?

嗯,这就对了。所有的理论知识都要应用于实践,否则也就没有了存在价值。在我的实践应用当中,接口用得最多的就是 Mybatis 的 Mapper 接口。

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解(就是你在前面见到的增删改查四大注解)来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

当我们配置好了 MyBatis 环境后,可以直接通过以下语句来调用注射器接口。

@Servicepublic class CityService {    @Autowired    private CityMapper cityMapper;?    public void init() {            List<City> citys = cityMapper.getCitys();        }    }}

在注射器接口中,也只会存在那些与数据库查询相关的抽象方法,就像你看到的 List<City> getCitys();。一个注射器接口 + 注射器注解就可以增删改查数据库,是不是感觉很神奇?

05、

这篇文章的目的是帮助更多的读者了解和掌握抽象类、接口的特点,以及不同的使用场景,通过我整篇文章的努力,我相信你一定若有所获——这也是我写作的最强动力。最后,感谢各位的阅读哦。

Java 极客技术公众号,是由一群热爱 Java 开发的技术人组建成立,专注分享原创、高质量的 Java 文章。如果您觉得我们的文章还不错,请帮忙赞赏、在看、转发支持,鼓励我们分享出更好的文章。

关注公众号,大家可以在公众号后台回复“博客园”,免费获得作者 Java 知识体系/面试必看资料。

原文地址:https://www.cnblogs.com/justdojava/p/11211589.html

时间: 2024-11-09 03:56:51

接口和抽象类,傻傻分不清楚?的相关文章

jQuery、DOM对象傻傻分不清楚

初学jQuery时,经常分辨不清楚哪些是jQuery对象,哪些是DOM对象.这是十分不好的现象.必须明确区分何为jQuery对象.何为DOM对象,对于后续的学习.理解才更方便. 先从DOM对象开始,之后在谈谈jQuery对象(jq对象基于DOM对象). DOM.DOM对象 DOM(Document Object Model,文档对象模型),DOM是W3C的标准.定义了访问HTML和XML文档的标准. 文档对象模型是中立于平台和语言的接口,允许程序和脚本动态的访问和更新文档的内容.结构以及样式,更

傻傻分不清之 Cookie、Session、Token、JWT

傻傻分不清之 Cookie.Session.Token.JWT 什么是认证(Authentication) 通俗地讲就是验证当前用户的身份,证明“你是你自己”(比如:你每天上下班打卡,都需要通过指纹打卡,当你的指纹和系统里录入的指纹相匹配时,就打卡成功) 互联网中的认证: 用户名密码登录 邮箱发送登录链接 手机号接收验证码 只要你能收到邮箱/验证码,就默认你是账号的主人 什么是授权(Authorization) 用户授予第三方应用访问该用户某些资源的权限 你在安装手机应用的时候,APP 会询问是

低俗文章之傻傻分不清楚的IC和ID卡

声明: PS.正如影片"低俗喜剧"开头导演所警告:内容充满不雅用语.成人题材.歧视.色情性描写,因此,本文章与"低俗喜剧"一样被编订为比家长指引级别更高一级的专家指责类别,若未能接受以上内容--大家立即点击浏览器右上角的红色X(Linux以及OSX的请点击左上角的X). 本文作者(即本人:黑板)以及背后技术团队(RadioWar)并无任何恶意语咒骂.针对任何个人或团队,只为求戏说RFID,故此因本低俗文章而引起各位不安.不适.不快.甚至不举,本文作者以及其背后技术团

驳《低俗文章之傻傻分不清楚的IC和ID卡》:ID和IC之我见

我很认真看完了<低俗文章之傻傻分不清楚的IC和ID卡>这篇文章:http://www.freebuf.com/articles/wireless/9451.html 我可以直接表明,我就是对你发表的关于RFID的几篇帖子口气很不爽,既然你这篇文章中间主题是就事论事,我也就事论事一番. 1.ID卡就是大家常常说的低频卡 2.其厚度较为厚,并且只是只读,只保存一串唯一身份识别序列号 3.ID卡不存在任何其他的数据 这三个是你总结的对方的观点,反观你的本篇文章,其中你用大段的话来描述,低频卡不全是I

16、Cocos2dx 3.0游戏开发找小三之Node:父节点、子节点、傻傻分不清楚

重开发者的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/30476133 Cocos2d-x 采用了场景.层.精灵的层次结构来组织游戏元素, 与此同时,这个层次结构还对应了游戏的渲染层次,因此游戏元素可以组织成树形结构,称作渲染树. Cocos2d-x 把渲染树上的每一个游戏元素抽象为一个节点,即 Node. 一切游戏元素都继承自 Node,因此它们 都具有 Node 所提供的特性. Node 定义了一个可绘制

Web前端后端傻傻分不清,

1. Web前端后端傻傻分不清 原创 2016年12月25日 19:50:08 7178 0 2 前言 ??做C开发将近六年,基本上没有接触过web相关的东西,原来听别人说web相关的东西的时候也是分不太清楚到底哪个是前端哪个是后台,前端和后台又是怎么配合着工作的?经过各方法搜索,很多类似的疑问终于得以弄明白. ??使用html.Javascript写的是Web前端,它不用向服务器(比如apache.nginx.tomcat等)交互在浏览器端就执行完了,比如使用Javascript弹出一个警告框

谈一谈让人傻傻分不清的1G,2G,3G,4G……

浅谈让人傻傻分不清的1G,2G,3G,4G-- 虽然大学里学过计算机网络,平时也总是看网上不停的喷着1G,2G,3G,4G到底是啥,但总觉得隔靴搔痒,看不出其本质区别,我不想详解其中的又臭又长的关键技术,就从大家能看明白的概念上说一说这些不同代网络技术的区别. 先从概念和区别说起 1G:没啥好说的,估计是有了后来的2.3G,才想起称呼原来的为1G.1G采用FDMA(模拟和频分多址技术),可实现区域的移动性服务,代表是第一代模拟制式手机,大哥大,通话锁定在一定频率,使用可调频电台就可以窃听电话,保

JS魔法堂:属性、特性,傻傻分不清楚

一.前言 或许你和我一样都曾经被下面的代码所困扰 var el = document.getElementById('dummy'); el.hello = "test"; console.log(el.getAttribute('hello')); // IE67下输出test,其他浏览器输出null “搞毛啊?”,苦逼的Jser对着浏览器大呼一声.然后就用下面蹩脚的方式草草处理掉了. function getAttr(el, prop){ return el[prop] || el

基础挺重要的,以前堆和栈傻傻分不清楚,这下知道了

堆与栈在内存里是怎么分配的? 对于初学编程的人员来说,变量在内存中是分配在堆中还是在栈中,往往不甚明白,今天我来清晰简单的讲解下. 步骤/方法 1 ?当我们看到一个变量类型是已知的,就分配在栈里面,比如INT,Double等.其他未知的类型,比如自定义的类型,因为系统不知道需要多大,所以程序自己申请,这样就分配在堆里面. 2 值类型与引用类型的分配,如图: 3 简单来说,值类型是分配在栈里面,引用类型分配在堆里面. 那从内存的分配角度来看,是因为值类型,已经知道了类型的范围大小,可以进行有效分配