#一.接口
接口在Java当中是通过关键字interface来实现,接口不是类,所以也不能被实例化,接口是用来建立类与类之间的协议,它的提供的只是一种形式,而没有具体的实现。实现类实现(implements)接口,必须实现接口的全部方法
接口是抽象类的延伸,Java不允许多重继承(即不能有多个父类,只能有一个),但可以实现多个接口。在使用接口的过程中,就注意以下几个问题:
- 接口中不能有构造方法。
- 接口的所有方法自动被声明为public,而且只能为public,如果使用protected、private,会导致编译错误。
- 接口可以定义"成员变量",而且会自动转为public final static,即常量,而且必须被显式初始化。
- 接口中的所有方法都是抽象方法,不能包含实现的方法,也不能包含静态方法
- 实现接口的非抽象类必须实现接口的所有方法,而抽象类不需要
- 不能使用new来实现化接口,但可以声明一个接口变量,它必须引用一个实现该接口的类的对象,可以使用instanceOf来判断一个类是否实现了某个接口,如if (object instanceOf ClassName){doSth()};
在实现多接口的时候一定要注意方法名的重复
接口相关内容很简单,这里主要分析一下接口的作用和好处,以下是知乎的一个关于接口的问题,曾经你是否也要这样的疑问呢?
例如我定义了一个接口,但是我在继承这个接口的类中还要写接口的实现方法,那我不如直接就在这个类中写实现方法岂不是更便捷,还省去了定义接口?接口在java中的作用是什么?个人觉得只是一种规范。大家的看法呢?
得票最高的答案:
能问这个问题,说明(1)你很会思考(2)编程水平还是处于起步阶段。
“接口是个规范”,这句没错。
“不如直接就在这个类中写实现方法岂不是更便捷”,你怎么保证这个接口就一个类去实现呢?如果多个类去实现同一个接口,程序怎么知道他们是有关联的呢?
既然不是一个类去实现,那就是有很多地方有用到,大家需要统一标准。甚至有的编程语言(Object-C)已经不把接口叫 interface,直接叫 protocol。
统一标准的目的,是大家都知道这个是做什么的,但是具体不用知道具体怎么做。
比如说:
我知道 Comparable 这个接口是用来比较两个对象的,那么如何去比较呢?
数字有数字的比较方法,字符串有字符串的比较方法,学生(自己定义的类)也有自己的比较方法。
然后,在另外一个负责对象排序(不一定是数字喔)的代码里面,肯定需要将两个对象比较。
这两个对象是什么类型呢?
Object a,b?肯定不行,a > b 这样的语法无法通过编译。
int a,b?也不行?一开始就说了,不一定是数字。
…
所以,Comparable 就来了。他告诉编译器,a b 两个对象都满足 Comparable 接口,也就是他们是可以进行比较的。具体怎么比较,这段程序不需要知道。
所以,他需要一些具体的实现,Comparable 接口有一个方法,叫 compareTo。那么这个方法就是用来取代 <、> 这样的运算符。
因为运算符是编译器保留给内置类型(整数、浮点数)进行比较用的,而不是一个广义的比较运算。
如果你可以明白 JDK 自身库里面诸如 Comparable 这样已经有的接口,那么就很容易理解自己在开发程序的时候为什么需要用到接口了。
见:https://www.zhihu.com/question/20111251
##接口好处
-
接口是一些对外暴露的规则
以usb接口为例,不管什么样的外部设备,都可以插入到usb解耦上去,对应到java中,一批实现了同一个接口的类,他们是具备某种同一特质的,很容易实现多态。 -
提高了程序的扩展性
还拿usb来说,如果没有usb接口,鼠标怎么办?usb接口不紧可以插入鼠标,还可以插入移动硬盘。 -
降低了类之间的依赖关系(耦合性)
我们通过一些实际的例子给大家形象讲解一下
笔记本对外暴露接口,他不暴露不挺好的吗,也可以工作呀,但是紧跟着你发现一个问题,我想升级,硬盘升级到500g,怎么办,只能买一个新的。
不过厂商想了一个方法,想扩展,不用拆我的电脑。侧面开了一个口,usb接口,你只要买一个硬盘,支持我这个口,就可以用,然后你买了一个500g的移动硬盘,往上咔嚓一插就可以用了。哪个usb是不是功能扩展,是不是对外规则,他是不是就降低了移动硬盘和电脑的耦合性。鼠标也是,是不是降低了鼠标和笔记本的耦合性呀。
##继承和接口有何不同
有一个非常形象的例子
同学都有一些动作,学习呀,休息呀,我分析完,我发现很多学生抽烟。
接口他也属于共性的东西的,但是不是属于同一类,这个时候使用接口,是体系以外的功能扩展。接口是功能扩展用的,实现由子类来
继承是is-a,而接口是like-a,你像我中的一个。
比如很多学生抽烟这件事,抽烟就作为接口
##来自think in java的忠告
“确定接口是理想选择,因而应该总是选择接口而不是具体的类”。这其实是一种诱惑。当然,对于创建类,几乎在任何时候,都可以替代为创建一个接口和一个工厂。
许多人都掉进了这种诱惑的陷阱,只要有可能就去创建接口和工厂。这种逻辑看起来好像是因为需要使用不同的具体实现,因此总是应该添加这种抽象性。这实际上已经变成了一种草率的设计优化。
任何抽象性都应该是应真正的需求而产生的。当必需时,你应该重构接口而不是到处添加额外的级别的间接性,并由此带来的额外的复杂性。这种额外的复杂性非常显著。
恰当的原则应该是优先选择类而不是接口。从类开始,如果接口的必需性变得非常明确,那么就进行重构。接口是一种重要的工具,但是它们容易被滥用。
#二.抽象类
比较容易理解
抽象类是用来描述抽象行为的,比如Animal,我们不知道Animal具体有会有什么样的行为,只有具体的动物类,如Dog,Cat才有具体的行为,才能够被实例化。抽象类是实现多态的一种机制,它可以包含具体方法(有具体实现的方法),也可以包含抽象方法,而继承它的子类必须实现这些方法,下面总结了一下抽象类的特性:
- 抽象类不能被实例化,但可以有构造函数
- 抽象方法必须由子类进行重写
- 只要包含一个抽象方法的类,就必须定义为抽象类,不管是否还包含其他方法
- 抽象类中可以包含具体的方法,也可以不包含抽象方法
- 抽象类可以包含普通成员变量,其访问类型可以任意
- 抽象类也可以包含静态成员变量,其访问类型可以任意
- 子类中的抽象方法不能与父类的抽象方法同名
- abstract不能与private、static、final或native并列修饰同一个方法
#三.接口和抽象类的区别
#参考资料
http://www.jianshu.com/p/2b5a9bdcd25f