接口(英文:Interface
),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。接口并不是类
,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。接口无法被实例化
,但是可以被实现
。一个实现接口的类,必须实现接口内所描述的所有方法,否则就有必要声明为抽象类。
简单来总结下:接口类似一个只有抽象方法的抽象类,就像抽象类一样,它无法被实例化,必须要有实现类它才会有意义。
一、接口的定义&用法
1.1:例子&用法
用最简单最好理解的方式来说,所谓接口就是一个只有抽象方法的”抽象类“(这里只是类比,接口不是类),接口跟抽象类、抽象类跟普通类之间的区别和意义,我们放到第二节来讲,这里看个案例:
代码块11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| public interface TrafficTools { String move(); }
public class HighSpeedRailway implements TrafficTools { private String speed = "306km/h"; @Override public String move() { return "靠行走在" + railway() + "上的火车,以" + speed + "的速度"; } public String railway() { return "高速轨道铁路"; } public void setSpeed(String speed) { this.speed = speed; } } public class Plane implements TrafficTools { private String company = "华航"; @Override public String move() { return "靠" + company + "的飞机,以" + fly() + "的方式"; } public String fly() { return "飞行"; } public void setCompany(String company) { this.company = company; } }
|
接口不允许有属性,可以简单理解接口是定义一系列动作(即方法)的标准,任意符合这个标准的类都可以实现这个接口,比如例子中的飞机和高铁类,都可以实现TrafficTools接口,因为它们都是交通工具,都有move这一基本标准。现在定义好了交通工具,让我们再定义旅游类,它是一个抽象类,抽象出来了旅行所具备的属性和方法:
代码块21 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| public abstract class Tour { private String start; private String end; private String name; private TrafficTools tools; public abstract String kind(); public abstract String play(); public String getTour() { return kind() + tools.move() + ",从" + start + "出发,抵达" + end + play(); } public void setStart(String start) { this.start = start; } public void setEnd(String end) { this.end = end; } public void setName(String name) { this.name = name; } public String getName() { return name; } public void setTools(TrafficTools tools) { this.tools = tools; } }
public class AloneTour extends Tour { @Override public String kind() { return super.getName() + "的个人旅行"; } @Override public String play() { return "完成了自己的个人旅行,顺便修了个仙儿~"; } } public class HoneyMoonTour extends Tour { @Override public String kind() { return super.getName() + "的蜜月旅行"; } @Override public String play() { return "玩了专为情侣准备的蜜月项目"; } }
|
让我们来具体测试下:
代码块31 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public static void main(String[] args) { Tour myAloneTour = new AloneTour(); myAloneTour.setStart("东京都"); myAloneTour.setEnd("雏见泽"); myAloneTour.setName("前原圭一"); TrafficTools tools = new HighSpeedRailway(); myAloneTour.setTools(tools); System.out.println(myAloneTour.getTour()); Tour hmTour = new HoneyMoonTour(); hmTour.setStart("木叶忍者村"); hmTour.setEnd("涡の国"); hmTour.setName("漩涡鸣人&日向雏田"); TrafficTools tools2 = new Plane(); hmTour.setTools(tools2); System.out.println(hmTour.getTour()); }
|
上方代码输出如下:
代码块41 2
| 前原圭一的个人旅行靠行走在高速轨道铁路上的火车,以306km/h的速度,从东京都出发,抵达雏见泽完成了自己的个人旅行,顺便修了个仙儿~ 漩涡鸣人&日向雏田的蜜月旅行靠华航的飞机,以飞行的方式,从木叶忍者村出发,抵达涡の国玩了专为情侣准备的蜜月项目
|
看完本例,你可以了解接口的基本用法。
非常重要的一点:接口支持多继承,一个类可以同时实现多个接口
举个非常简单的例子:
代码块51 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| public interface A { void a(); } public interface B { void b(); } public interface C extends A, B { void c(); } public interface D { void d(); } public class E implements C, D { @Override public void c() { } @Override public void a() { } @Override public void b() { } @Override public void d() { } }
public abstract class F implements C, D { abstract void f(); void f2() { } @Override public void c() { } } public class G extends F { @Override void f() { } @Override public void a() { } @Override public void b() { } @Override public void d() { } }
|
接口、抽象类、类之间的关系不管依赖多么复杂,当方法发生调用时,均遵循上一章节讲的”就近调用
“规则。
1.2:接口与类相似点
- 一个接口可以有多个方法。
- 接口文件保存在
.java
结尾的文件中,文件名使用接口名。
- 接口的字节码文件保存在
.class
结尾的文件中。
- 接口相应的字节码文件必须在与包名称相匹配的目录结构中。
1.3:接口与类的区别
- 接口不能用于实例化对象。
- 接口没有构造方法。
- 接口中所有的方法必须是抽象方法。
- 接口不能包含成员变量,除了
static
和final
变量。
- 接口不是被类继承了,而是要被类实现。
- 接口支持
多继承
。
二、类、抽象类、接口之间的区别
在java的世界里,一切皆对象,而对象又是根据类的模板生成的符合类定义的一个个体,所以类是对一类事物的具体抽象。
抽象类无法被实例化,它是为普通类服务的,简单来说,普通类用来抽象真实存在的事物,给它们分类(猫、狗、数据库对象等),而抽象类是位于普通类上层的用来给类分类的,比如猫狗,都可以拆分成猫类,狗类,但是猫和狗具有相同意义的属性和方法,例如年龄、吃饭睡觉等,这些就可以再次被分类,成为猫和狗的父类,比如动物,你会发现不光猫狗具备这些被抽象出来的属性和方法,日后如果定义一个人类,同样也是符合的,抽象类就是为类分类而生的,它必须要有子类继承才有意义,抽象类可以自己定义方法的实现,也可以把一些方法全部交给子类去实现,如果一个抽象类里并不存在被抽象出来的属性,只有一些行为规范,而且这些行为规范抽象类自己实现没有意义,只能交给子类去实现,这个时候就可以将抽象类里的方法全部定义成抽象方法(现在很像接口了对吧),而接口就是这种位于上层里仅定义行为规范的一种结构。