接口内部结构:
- 可以声明:
属性:必须使用public static final修饰
方法:jdk8之前:声明抽象方法,修饰为public abstract
jdk8:声明静态方法、默认方法
jdk9:声明私有方法
- 不可以声明:构造器、代码块等
接口与类的关系:实现关系
格式:
class A [extends SuperA] implements B[,C,...] {}
- A相较于SuperA来讲,叫做子类
- A相较于B,C来讲,叫做实现类
- 类可以实现多个接口
- 类针对于接口的多实现,一定程度上就弥补了类的单继承的局限性
- 类必须将实现的接口中的所有抽象方法都重写(或实现),方可实例化,否则此实现类必须声明为抽象类
public class InterfaceTest {
public static void main(String[] args) {
Plane p = new Plane();
System.out.println(Plane.MAX_SPEED); // 1000
System.out.println(Flyable.MAX_SPEED); // 1000
p.attack(); // 飞机可以攻击
p.fly(); // 飞机飞
}
}
// 接口
interface Flyable {
public static final int MIN_SPEED = 0;
// 默认被public static final修饰
int MAX_SPEED = 1000;
// 方法可以省略public abstract声明
void fly();
}
interface Attackable {
void attack();
}
// 类实现接口
class Plane implements Flyable, Attackable {
@Override
public void fly() {
System.out.println("飞机飞");
}
@Override
public void attack() {
System.out.println("飞机可以攻击");
}
}
接口与接口的关系:继承关系,且可以多继承
// 接口的继承关系
interface AA {
void m1();
}
interface BB {
void m2();
}
interface CC extends AA, BB {
}
class DD implements CC {
@Override
public void m1() {
// TODO Auto-generated method stub
}
@Override
public void m2() {
// TODO Auto-generated method stub
}
}
接口的多态性:
接口名 变量名 = new 实现类对象
例如上例
Plane p = new Plane();
p.attack(); // 飞机可以攻击
p.fly(); // 飞机飞
// 多态 此时p有fly()方法,没有attack()方法
Flyable p = new Plane();
p.attack(); // 报错
p.fly(); // 飞机飞
抽象类和接口的区别
共性:都可以声明抽象方法
都不能实例化
不同:抽象类一定有构造器,接口没有构造器
类与类之间是继承关系,类与接口之间是实现关系,接口与接口之间是多继承关系
在开发中,抽象类作为一个模版,接口作为一个标准或是表示一种能力
JDK8、9中的接口新特性
// jdk8,9 接口新特性
interface CompareA {
// jdk8中:静态方法
public static void m1() {
System.out.println("CompareA:北京");
}
// jdk8中:默认方法 必须有default,否则会被认为是抽象方法
// 可以被实现类重写
// 当实现类实现了两个接口,两个接口中定义了同名同参数的默认方法,会产生“接口冲突”,此时必须重写该方法
// 当实现类的父类与接口有同名同参的默认方法,优先调用类方法,“类优先原则”
public default void m2() {
System.out.println("CompareA:上海");
}
// jdk9中:私有方法
private void m3() {
// 供接口内部默认方法使用
}
}
class SubClass1 implements CompareA {
public void method() {
// 调用接口默认方法
CompareA.super.m2();
}
}
class SubClassTest {
public static void main(String[] args) {
// 接口中声明的静态方法只能被接口来调用,不能使用其实现类进行调用
CompareA.m1(); // CompareA:北京
// SubClass.m1(); // 报错
SubClass1 s1 = new SubClass1();
s1.m2(); // CompareA:上海
s1.method(); // CompareA:上海
}
}