接口(英文:Interface)是Java中非常重要的内容,初学的时候可能感受不深,但是在做项目的时候,对面向接口编程的运用就变得尤为重要,不过这是后话了。现在先讨论假如是刚刚接触接口这个概念,该怎么玩?如果是看过我之前文章的朋友应该了解,在遇到一个新概念的时候,我一般思考框架是先问下面三个问题:

1.这个东西有什么用?用来干什么的?它的意义在哪里?(显然,如果是没用的东西,就没必要浪费时间了;其实,弄懂了这个问题,就掌握了50%)

2.这个概念或者技能点怎么用?也就是它的表现形式,如关键字、修饰词、语法什么的。。。(这个占20%)

3.这个东西在用的过程中,有哪些关键点和细节点?(这个占30%)

上面三个问题搞清楚了,剩下的就是去用了。。。“无他,但手熟尔。”

一、接口有什么用?它的意义在哪里?

回答这个问题,两句话就够了:

1.接口表示一种能力

2.接口表示一种约定

先来看第一点“接口表示一种能力”,举个栗子:

需求:现在要创造一个蜘蛛侠。人有“唱歌”和“考试”的功能,蜘蛛有“爬行”和“吐丝”的功能。

分析:首先蜘蛛侠是一个人,他有蜘蛛的能力。按照面向对象思想,可以将人和蜘蛛分别定义成抽象类。但是,不能让蜘蛛侠在继承人的同时又继承蜘蛛。两个原因:一、蜘蛛侠不是蜘蛛,不符合继承中 【is a】的关系;二、Java只支持单继承。如何解决这个问题呢?这时就要用到接口,接口是【has a】的关系。可以将蜘蛛的行为能力定义为接口,让蜘蛛侠继承人,实现蜘蛛的行为能力的接口。实现代码如下:

 public abstract class Person {        //定义Person抽象类
public abstract void sing(); //唱歌抽象方法
public abstract void exam(); //考试抽象方法
}
public interface ISpiderable { //定义一个蜘蛛的行为能力接口
public abstract void creep(); //爬行抽象方法
public abstract void shootWeb(); //吐丝抽象方法
}
public class SpiderMan extends Person implements ISpiderable{//继承人,实现蜘蛛的行为能力接口
String name = "彼得·帕克"; @Override
public void creep() { //实现爬行方法
System.out.println(name + " 在屋顶上爬,在树枝上爬,在夕阳下的草地上爬。。。");
}
@Override
public void shootWeb() { //实现吐丝方法
System.out.println(name + " 吐丝织网抓虫子");
}
@Override
public void sing() { //实现唱歌方法
System.out.println(name + " 往事不要再提~人生已多风雨~~");
}
@Override
public void exam() { //实现考试方法
System.out.println(name + " 上午考语文,下午考数学,明天考英语。。。");
}
}
public class Test { //测试一下
public static void main(String[] args) {
SpiderMan spiderman = new SpiderMan();
spiderman.creep();
spiderman.sing();
}
}

运行结果如下:

接着来,有天傍晚蜘蛛侠吃饱了没事儿闲溜达,在路边草丛里发现了雷神的大铁锤,于是他有具备了闪电的能力:

 public interface ILightningable {        //定义闪电能力接口
public abstract void lightning(); //闪电抽象方法
}
public class SpiderMan extends Person implements ISpiderable,ILightningable{//继承人,实现蜘蛛的行为能力接口,实现闪电能力接口
String name = "彼得·帕克"; @Override
public void creep() { //实现爬行方法
System.out.println(name + " 在屋顶上爬,在树枝上爬,在夕阳下的草地上爬。。。");
}
@Override
public void shootWeb() { //实现吐丝方法
System.out.println(name + " 吐丝织网抓虫子");
}
@Override
public void sing() { //实现唱歌方法
System.out.println(name + " 往事不要再提~人生已多风雨~~");
}
@Override
public void exam() { //实现考试方法
System.out.println(name + " 上午考语文,下午考数学,明天考英语。。。");
}
@Override
public void lightning() {
System.out.println(name + " 来一波闪电~"); //实现闪电方法
}
}
public class Test { //测试一下
public static void main(String[] args) {
SpiderMan spiderman = new SpiderMan();
spiderman.creep();
spiderman.sing();
spiderman.lightning();
}
}

运行结果如下:

通过上面的例子,“接口表示一种能力”已经算是不言而喻了,那么,为什么说“接口表示一种约定”?

首先,什么是“约定”?所谓的约定就是,这事儿就按咱哥俩说的规矩办,谁也别出幺蛾子。举个经典的打印机的例子:要求实现打印机的打印功能。打印机的墨盒可能是彩色的,也可能是黑白的,所用的纸张可以有多种类型,如A4、B5等,要命的是墨盒和纸张都不是打印机厂商生产的。那么,打印机厂商如何避免自的打印机与市场上的墨盒、纸张不符呢?

分析:有效解决该问题的途径是制定墨盒、纸张的约定或标准,然后打印机厂商按照约定对墨盒、纸张提供支持,这样一来,无论最后使用的是厂商张三还是厂商王麻子提供的墨盒或纸张,只有符合统一的约定,打印机都可以打印。当然,“接口(Interface)”就是这样一种约定。打印机打印功能实现如下:

 public interface IInkBox {        //定义墨盒接口,约定墨盒的标准
public String getColor(); //返回墨盒的颜色
}
public interface IPaper { //定义纸张的接口,约定纸张的标准
public String getSize();//返回纸张的种类
}
public class Printer{ //定义打印机类,引用墨盒接口、纸张接口实现打印功能
IInkBox inkbox=null;
IPaper paper=null;
public Printer(IInkBox inkbox,IPaper paper) { //构造函数,以接口类型为形参实现多态
this.inkbox = inkbox;
this.paper = paper;
}
public void printer() { //实现打印功能
System.out.println("使用"+inkbox.getColor()+"墨盒在"+paper.getSize()+"纸张上打印。");
}
}
public class ColorInkBox implements IInkBox{ //墨盒厂商按照墨盒接口实现彩色墨盒ColorInkBox类
public String getColor() {
return "彩色";
}
}
public class GrayInkBox implements IInkBox{ //墨盒厂商按照墨盒接口实现黑白墨盒GrayInkBox类
public String getColor() {
return "黑白";
}
}
public class A4Paper implements IPaper{ //A4纸类实现纸张接口
public String getSize() {
return "A4纸";
}
}
public class B5Paper implements IPaper{ //B5纸类实现纸张接口
public String getSize() {
return "B5纸";
}
}
public class Test { //测试一下
public static void main(String[] args) {
IInkBox colorInk = new ColorInkBox(); //接口IInk类型引用指向彩色墨盒ColorInkBox实现类的对象,多态
IInkBox grayInk = new GrayInkBox();
IPaper a4Paper = new A4Paper(); //接口IPaper类型引用指向A4纸A4Paper实现类的对象,多态
IPaper b5Paper = new B5Paper(); Printer printer = new Printer(colorInk,a4Paper); //创建Printer对象(组装打印机),彩色墨盒、A4纸
printer.printer();
Printer printer2 = new Printer(grayInk,b5Paper); //创建Printer对象(组装打印机),黑白墨盒、B5纸
printer2.printer();
}
}

运行结果如下:

功能实现,这就是“接口表示一种约定”。

二、接口怎么用?它的表现形式?

其实,从上面的例子中聪明的你肯定已经大致知道接口怎么用了,下面就总结一下Java中接口的定义语法和类实现接口的语法如下:

  [修饰词] interface 接口名 extends 父接口1,父接口2,....{

    //常量定义

    //抽象方法定义

  }

  class 类名 extends 父类名 implements 接口1,接口2,...{

    //类成员

  }

【关于接口用法的说明(其实,初学时不用都记住,先掌握关键点用起来再说,报几次错再回来补细节)】:

1.如果修饰词是public,则该接口在整个项目中可见;如果省略修饰词,则该接口只在当前包中可见。

2.接口中只能定义常量。接口中的属性都会自动用 public static final 修饰,即接口中的属性都是全局静态常量,必须在定义时指定初始值。

3.接口中所有方法都是抽象方法,都会自动用 public abstract 修饰,即接口中只有全局抽象方法。

4.接口之间可以通过extends实现继承关系,一个接口可以继承多个接口,但接口不能继承类。

5.接口的实现类必须实现接口的全部方法,否则就变成了抽象类。

三、接口使用的关键点?

了解接口很重要的一点就是它和抽象类的区别,这两个东西确实很像,都有继承,都有抽象方法,有种不严谨的说法甚至说“可以把接口当作一种极端的抽象类”,这么说有一定道理,但是接口和抽象类还是有很大的不同:

【语法方面】:

1.抽象类中属性可以有常量、变量,接口中只能是 public static final 修饰的常量;

2.抽象类中方法可以有抽象方法、普通成员方法,接口中只能有抽象方法;

3.抽象类只能单继承,接口可以继承多个接口;

4.一个类只能继承一个抽象类,一个类可以实现多个接口。

【设计方面】:

1.抽象类是对事物的抽象,接口是对行为的抽象。就像上面蜘蛛侠的例子,抽象类 Person 是抽象人这个事物,接口 ISpiderable 是抽象蜘蛛的行为能力。

2.设计模式不同,抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。什么是模板式设计?最简单例子,大家都用过ppt里面的模板,如果用模板A设计了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A了,如果它们的公共部分需要改动,则只需要改动模板A就可以了,不需要重新对ppt B和ppt C进行改动。而辐射式设计,就像上面打印机的例子,如果改变了纸张IPaper的接口,那么纸张的实现类 A4Paper() 和 B5Paper()就都要修改。也就是说对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更;而对于接口则不行,如果接口进行了变更,则所有实现这个接口的类都必须进行相应的改动。

浅谈Java接口的更多相关文章

  1. 浅谈Java接口(Interface)

    浅谈Java接口 先不谈接口,不妨设想一个问题? 如果你写了个Animal类,有许多类继承了他,包括Hippo(河马), Dog, Wolf, Cat, Tiger这几个类.你把这几个类拿给别人用,但 ...

  2. 浅谈Java中接口与抽象类的异同

    浅谈Java中接口与抽象类的异同 抽象类和接口这两个概念困扰了我许久,在我看来,接口与抽象类真的十分相似.期间也曾找过许许多多的资料,参考了各路大神的见解,也只能是简简单单地在语法上懂得两者的区别.硬 ...

  3. 浅谈JAVA集合框架

    浅谈JAVA集合框架 Java提供了数种持有对象的方式,包括语言内置的Array,还有就是utilities中提供的容器类(container classes),又称群集类(collection cl ...

  4. 浅谈Java中的深拷贝和浅拷贝(转载)

    浅谈Java中的深拷贝和浅拷贝(转载) 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: ...

  5. !! 浅谈Java学习方法和后期面试技巧

    浅谈Java学习方法和后期面试技巧 昨天查看3303回复33 部落用户大酋长 下面简单列举一下大家学习java的一个系统知识点的一些介绍 一.java基础部分:java基础的时候,有些知识点是非常重要 ...

  6. 浅谈Java中的深拷贝和浅拷贝

    转载: 浅谈Java中的深拷贝和浅拷贝 假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(bool ...

  7. 浅谈Java的集合框架

    浅谈Java的集合框架 一.    初识集合 重所周知,Java有四大集合框架群,Set.List.Queue和Map.四种集合的关注点不同,Set 关注事物的唯一性,List 关注事物的索引列表,Q ...

  8. 浅谈java类集框架和数据结构(2)

    继续上一篇浅谈java类集框架和数据结构(1)的内容 上一篇博文简介了java类集框架几大常见集合框架,这一篇博文主要分析一些接口特性以及性能优化. 一:List接口 List是最常见的数据结构了,主 ...

  9. 浅谈 Java 主流开源类库解析 XML

    在大型项目编码推进中,涉及到 XML 解析问题时,大多数程序员都不太会选用底层的解析方式直接编码. 主要存在编码复杂性.难扩展.难复用....,但如果你是 super 程序员或是一个人的项目,也不妨一 ...

随机推荐

  1. 【.net 深呼吸】WPF 中的父子窗口

    与 WinForm 不同,WPF 并没有 MDI 窗口,但 WPF 的窗口之间是可以存在“父子”关系的. 我们会发现,Window 类公开了一个属性叫 Owner,这个属性是可读可写的,从名字上我们也 ...

  2. NHibernate教程(7)--并发控制

    本节内容 什么是并发控制? 悲观并发控制(Pessimistic Concurrency) 乐观并发控制(Optimistic Concurrency) NHibernate支持乐观并发控制 实例分析 ...

  3. 获取windows任务栏高度的方法

    方法一: TRect rt; SystemParametersInfo(SPI_GETWORKAREA, , &rt, ); //任务栏在下面的高度 int y = ::GetSystemMe ...

  4. 【集美大学1411_助教博客】团队作业5——测试与发布(Alpha版本)

    同学们好像都进入了状态,任务都完成的不错,测试与发布是一个软件的非常重要的环节,每年双11前夕是阿里巴巴加班最严重的时期,这是因为他们在不断的测试,因为他们不想在双11到来之时有任何差池.所以无论你的 ...

  5. 结对实验---基于GUI的四则运算

    详细代码:https://git.coding.net/wangluo24/NO.2.git 结对伙伴:吕志哲(201421123021) &本人.许明涛 201421123024 一.题目要 ...

  6. 团队作业4——第一次项目冲刺(Alpha版本)日志集合处

    Day 1: http://www.cnblogs.com/TeamOf/p/6754373.html Day 2: http://www.cnblogs.com/TeamOf/p/6754410.h ...

  7. 201521123057 《Java程序设计》 第8周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容 2. 书面作业 1.List中指定元素的删除(题目4-1) 1.1 实验总结 答:remove中注意应该使用eq ...

  8. 201521123112《Java程序设计》第2周学习总结

    1.本周学习总结 本周在课堂面授课粗略讲了<Java学习笔记>中的第三章,其内容大部分都与上学期学习的数据结构差不多,所以只是粗略的复习了一下就带过,然后通过将PTA上的实验便于我们本周的 ...

  9. Java课程设计——GUI密码生成器团队博客

    1.团队名称.团队成员介绍(需要有照片) 1.1团队名称 小黄人 1.2团队成员介绍 吴玲:组长,现任院就业会策划部副部长 郭琪容:组员,现任院硬件协会会长 2. 项目git地址 吴 玲 郭琪容 3. ...

  10. 201521123062《Java程序设计》第10周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 2. 书面作业 1.finally 题目4-2 1.1 截图你的提交结果(出现学号) 1.2 4-2中fin ...