接口和类很相似,但绝对不是类。类描述对象的属性和方法。接口则包含类要实现的方法。
声明时用 interface关键字而非class。
[可见度] interface 接口名称 [extends 其他的接口名] {
// 声明变量
// 抽象方法
}
当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。
类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。
接口特性
- 接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
- 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。
- 接口中的方法是不能在接口中实现的(定义为抽象方法),只能由实现接口的类来实现接口中的方法。
- 接口可以多继承
新增特性:
- JDK7以前:接口中只能定义抽象方法;
- JDK8:接口可以定义有方法体的方法(默认(default)、静态)。
- 默认方法:
- 解决:接口升级;
- 格式:public default 返回值类型 方法名(…){…};
- 不是抽象方法,在实现类中不强制重写。有需要重写时,去掉default在重写。(不重写也可以直接调用 )
- 如果实现了多个接口,多个接口中存在重名默认方法,则必须重写该方法。
- 静态方法:
- 格式:public static 返回值类型 方法名(…){…};
- 只能通过接口名调用。
- 默认方法:
- JDK9:可定义私有方法。
- 允许将方法定义为 private,使得某些复用的代码不会把方法暴露出去。更多内容可参考 Java 9 私有接口方法。
- 目的:只服务于接口的函数,不想泄露。
- 分为普通的私有方法(服务于默认方法)和静态的私有方法(服务于静态方法)。
适配器设计模式:
适配器设计模式是一种结构性设计模式,用于解决不同接口之间的兼容性问题。它允许将一个类的接口转换成客户端所期望的另一种接口,从而使原本由于接口不兼容而无法一起工作的类能够协同工作。
适配器类通过组合或继承的方式,将源类的功能包装到目标接口中。这样,客户端可以通过目标接口与源类进行交互,而无需了解源类的具体实现。
示例:
Animal.java:
package main.Interface;
public abstract class Animal {
private String name;
private int age;
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public abstract void eat();
}
Swim.java:
package main.Interface;
public interface Swim {
public abstract void swim();
public default void swimtodeath(){
death();
}
private void death(){
System.out.println("gone");
}
}
Frog.java:
package main.Interface;
public class Frog extends Animal implements Swim{
public Frog() {
}
public Frog(String name, int age) {
super(name, age);
}
@Override
public void eat(){
System.out.println("青蛙吃虫子");
}
@Override
public void swim(){
System.out.println("青蛙蛙泳");
}
}
Rabbit.java:
package main.Interface;
public class Rabbit extends Animal{
public Rabbit() {
}
public Rabbit(String name, int age) {
super(name, age);
}
@Override
public void eat(){
System.out.println("兔子吃胡萝卜");
}
}
Dog.java:
package main.Interface;
public class Dog extends Animal implements Swim{
public Dog() {
}
public Dog(String name, int age) {
super(name, age);
}
@Override
public void eat(){
System.out.println("狗吃屎");
}
@Override
public void swim(){
System.out.println("狗刨游泳");
}
@Override
public void swimtodeath(){
System.out.println("DOG:FUCK!");
}
}
Test.java:
package main.Interface;
public class InterfaceTest {
public static void main(String[] args) {
Dog dog=new Dog();
Frog frog =new Frog();
Rabbit rabbit=new Rabbit();
dog.eat();
frog.eat();
rabbit.eat();
dog.swim();
frog.swim();
dog.swimtodeath();
frog.swimtodeath();
}
}
运行结果:
狗吃屎
青蛙吃虫子
兔子吃胡萝卜
狗刨游泳
青蛙蛙泳
DOG:FUCK!
gone
分析:
狗、兔、青蛙都继承于抽象类Animal,都需要重写抽象方法eat();
Swim中:swimtodeat为默认方法,无需重写。对于这个方法,调用了接口内的私有方法death();
狗、青蛙都实现了Swim这个接口,实现了swim()的多态。其中狗重写了swimtodeath()。青蛙实现默认的swimtodeath()。