接口
接口
一、什么是接口
接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
二、接口的语法
- 接口相当于特殊的抽象类,定义方式、组成部分与抽象类类似。
1 | [可见度] interface 接口名称 [extends 其他的接口名] { |
案例1:
Interface1.java
1 | package demo1; |
Interface.java
1 | package demo1; |
TestInterface.java
1 | package demo1; |
运行结果:
接口有以下特性:
- 接口是隐式抽象的,当声明一个接口的时候,不必使用
abstract
关键字。 - 接口中每一个变量是静态常量,隐式以
public static final
修饰。 - 接口中每一个方法也是隐式抽象的,隐式以
public abstract
修饰,声明时同样可省略abstract
关键字。 - 接口中的方法、变量都是
public
的。
案例2:接口中的变量、方法都会隐式修饰,public static final
与public abstract
可省略。
1 | public interface Interface1{ |
案例3:接口是隐式抽象,隐式使用abstract
修饰,与抽象类相似,无法创建对象
1 | public class TestInterface { |
运行结果:
三、接口表示能力
- 微观概念:接口是一种能力和约定。
- 接口的定义:代表某种能力
- 方法的定义:能力的具体要求
- Java为单继承,当父类的方法种类无法满足子类需求时,可实现接口扩充子类能力。
案例1:让人具有飞的能力
Person.java
1 | public class Person implements Flyable{ |
Flyable.java
1 | //定义表示能力的接口后面一般加able |
TestPerson.java
1 | public class TestPerson { |
运行结果:
- 接口支持多实现,可为类扩充多种能力。
案例2:让人具有飞和游的能力
Swimable.java
1 | public interface Swimable { |
Person.java
1 | public class Person implements Flyable,Swimable{ |
TestPerson.java
1 | public class TestPerson { |
运行结果:
四、接口的规范
- 任何类在实现接口时,必须实现接口中所有的抽象方法,否则此类为抽象类。
- 实现接口中的抽象方法时,访问修饰符必须为
public
。 - 一个类可以实现多个接口
- 一个接口可以继承另一个接口,但是不能继承类。
五、接口的多态
接口引用:
- 同父类一样,接口也可声明为引用,并指向实现类对象。
- 注意:
- 向上转型后,仅可调用接口中所声明的方法,不可调用实现类中独有的方法。
- 如需使用实现类中的独有方法,可向下转型,强转回实现类本身类型。
Animal.java
1 | public class Animal { |
Runnable.java
1 | public interface Runnable { |
Swimmable.java
1 | public interface Swimmable { |
TestPolymorpfic.java
1 | public class TestPolymorpfic { |
运行结果:
六、常见关系
- 类与类
- 单继承:
extends 父类名称
- 单继承:
- 类与接口
- 多实现:
implements 接口名称1,接口名称2,接口名称3,...
- 多实现:
- 接口与接口
- 多继承:
extends 父接口1,父接口2,父接口3,...
- 多继承:
七、常量接口与标记接口
- 常量接口:将多个常用于表示状态或固定值的变量以静态常量的形式定义在接口中统一管理,提高代码的可读性。
Interface.java
1 | public interface Interface { |
TestInterface.java
1 | public interface TestInterface { |
运行结果:
- 标记接口:标记接口中没有包含任意成员,仅仅用作标记,
Serializable
、Cloneable
InterfaceC.java
表示该对象可克隆
1 | public interface InterfaceC extends Cloneable{ |
InterfaceS.java
表示该对象可序列化
1 | import java.io.Serializable; |
再来看看Serializable
、Cloneable
这两个接口中的内容,其实它们没有任何内容,仅仅用于标记。
标记接口是没有任何方法和属性的接口.它仅仅表明它的类属于一个特定的类型,供其他代码来测试允许做一些事情。
标记接口作用:简单形象的说就是给某个对象打个标(盖个戳),使对象拥有某个或某些特权。
例如:java.awt.event
包中的MouseListener
接口继承的 java.util.EventListener
接口定义如下:
1 | package java.util; |
没有任何方法的接口被称为标记接口。标记接口主要用于以下两种目的:
建立一个公共的父接口:
正如
EventListener
接口,这是由几十个其他接口扩展的Java API,你可以使用一个标记接口来建立一组接口的父接口。例如:当一个接口继承了EventListener
接口,Java虚拟机(JVM)就知道该接口将要被用于一个事件的代理方案。向一个类添加数据类型:
这种情况是标记接口最初的目的,实现标记接口的类不需要定义任何接口方法(因为标记接口根本就没有方法),但是该类通过多态性变成一个接口类型。
八、接口表示标准
接口表示一种标准,现实中比如耳机、充电器接口,必须要有一个标准,各大厂商按照这个标准进行生产,各种耳机、充电器才能够通用。
案例:Usb案例,各种外设遵循Usb接口,电脑才能够通用。接口回调。
Usb.java
Usb接口定义标准
1 | public interface Usb { |
Fan.java
风扇,按照Usb接口生产
1 | public class Fan implements Usb{ |
Keyboard.java
键盘,按照Usb接口生产
1 | public class Keyboard implements Usb{ |
Mouse.java
鼠标,按照Usb接口生产。
1 | public class Mouse implements Usb{ |
Compute.java
电脑,定义了三个Usb接口标准的USB
1 | public class Compute { |
TestCompute.java
1 | public class TestCompute { |
运行结果:
什么是接口回调:先有接口的使用者,后有接口的实现者。即上面案例,即先有电脑,后有鼠标、键盘等外设。
九、接口总结
9.1 与抽象类的异同
相同:
- 可编译成字节码文件。
- 不能创建对象。
- 可作为引用类型。
- 具备Object类中所定义的方法。
不同
- 所有属性都是公开静态常量,隐式使用
public static final
修饰 - 所有方法都是公开抽象方法,隐式使用
public abstract
修饰 - 没有构造方法、动态代码块、静态代码块
- 所有属性都是公开静态常量,隐式使用
- 1、抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
- 2、抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
- 3、接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
- 4、一个类只能继承一个抽象类,而一个类却可以实现多个接口。
9.2 接口与类的区别:
- 接口不能用于实例化对象。
- 接口没有构造方法。
- 接口中所有的方法必须是抽象方法,Java 8 之后 接口中可以使用 default 关键字修饰的非抽象方法。
- 接口不能包含成员变量,除了 static 和 final 变量。
- 接口不是被类继承了,而是要被类实现。
- 接口支持多继承。
注:JDK 1.8 以后,接口里可以有静态方法和方法体了。
注:JDK 1.8 以后,接口允许包含具体实现的方法,该方法称为”默认方法”,默认方法使用 default 关键字修饰。可参考 Java 8 默认方法。
注:JDK 1.9 以后,允许将方法定义为 private,使得某些复用的代码不会把方法暴露出去。可参考 Java 9 私有接口方法。