一. 接口
简单的说,接口就是一种被规范的标准,只要符合这个标准都可以通用,接口的表现
在于对行为的抽象.
1.1 创建接口的格式
格式1: public interface 接口名
格式2: interface 接口名
1.2 在JDK1.8之后, 在接口中可以定义实现的方法体是java8的一大特性,可以定义多个静态或者默认的方法, 下面的代码注释中说明了使用方法.
接口代码如下:
public interface Action {
// 接口中都是抽象方法和常量,不可能有非抽象方法,常量必须被赋值。
//接口中的方法默认是 public abstract
public abstract void eat();
//常量默认是 public static final
public static final int age = 20;
//Java8中接口中引入默认方法和静态方法,以此来减少抽象类和接口之间的差异
//静态方法
public static void method() {
/**
* 1、定义一个静态的带有方法体的方法
* 2、接口不能创建对象,调用静态方法不需要对象
* 3、接口名直接调用: Action.method();
*/
System.out.println("接口中静态方法");
}
//默认方法用default来修饰
/*
不同于静态方法,默认方法是一个非静态方法
对于非静态方法,只能通过对象进行调用
接口是不能直接new, 因此我们需要子类来实现接口
*
* */
default void methodDefault(){
System.out.println("default method in interface");
}
}
验证方法:
public class TestInterface implements Action{
@Override
public void eat() {
System.out.println("实现接口中的eat方法");
}
public static void main(String[] args) {
Action action = new TestInterface();
//调用接口中defaut方法
action.methodDefault();
//调用接口中的static方法 直接用 接口.方法();
Action.method();
}
}
打印如下:
default method in interface
接口中静态方法
1.3 接口有什么特点?
接口中声明全是public static final修饰的常量
接口中所有方法都是抽象方法
接口是没有构造方法的
接口也不能直接实例化
接口可以多继承
二. 抽象类和接口对比
抽象类是用来捕捉子类的通用特性的。接口是抽象方法的集合。
从设计层面来说,抽象类是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。
相同点:
接口和抽象类都不能实例化
都位于继承的顶端,用于被其他实现或继承
都包含抽象方法,其子类都必须覆写这些抽象方法
不同点:
参 数 | 抽象类 | 接口 |
声 明 | 抽象类使用abstract关键字声明 | 接口使用interface关键字声明 |
实 现 | 子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现 | 子类使用implements关键字来实现接口。它需要提供接口中所有声明的方法的实现 |
构 造 器 | 抽象类可以有构造器 | 接口不能有构造器 |
访 问 修 饰 符 | 抽象类中的方法可以是任意访问修饰符 | 接口方法默认修饰符是public. 并且 不允许定义为 private 或者protected |
多 继 承 | 一个类最多只能继承一个抽象类 | 一个类可以实现多个接口 |
字 段 声 明 | 抽象类的字段声明可以是任意的 | 接口的字段默认都是 static 和 final 的 |
备注:Java8中接口中引入默认方法和静态方法,以此来减少抽象类和接口之间 的差异。
现在,我们可以为接口提供默认实现的方法了,并且不用强制子类来实现它。
接口和抽象类各有优缺点,在接口和抽象类的选择上,必须遵守这样一个原则:
1 . 行为模型应该总是通过接口而不是抽象类定义,所以通常是优先选用接口,尽量 少用抽象类。
2. 选择抽象类的时候通常是如下情况:需要定义子类的行为,又要为子类提供通用 的功能。
从设计角度: 设计方面的区别
抽象类是对一种事物的抽象,即对类的抽象;而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为;接口是对类局部(行为)进行抽象。
比如:飞机和鸟不是同类的事物,但是它们都有一个共性---会飞。那么在设计的时候,可以将飞机设计为一个类Plane,将鸟设计为一个类Bird,但是不能将飞行这个特性也设计为一个类,因为它只是一个行为,并不是对一类事物的抽象描述。此时,可以将飞行设计为一个接口Fly,包含方法fly(),然后Plane和Bird分别根据自己的需要实现Fly这个接口。
然后至于有不同种类的飞机,比如战斗机、民用飞机等直接继承Plane即可,对于鸟类也是类似的,不同种类的鸟直接继承Bird类即可。
(从这个例子中能看出,继承是一个“是不是”的关系,而接口实现则是“有没有、具备不具备”的关系)