【java基础】接口

140 阅读3分钟

接口

一、接口的定义

语法:

public interface 接口名{

}

使用interface关键字来定义接口。

接口中可以定义属性和方法。

  • 属性默认是public static final的
  • 方法默认是public abstract的
public interface MyInterface {
    String name = "test";
    
    void say();
}

二、接口与抽象类的区别

经典面试题:

  • 抽象类中可以定义抽象方法,也可以定义普通方法。
  • 接口中只能定义抽象方法。
  • 抽象类中可以定义普通的实例属性,静态属性
  • 接口中只能定义public static final的属性
  • 抽象类中可以定义构造方法
  • 接口不能创建对象,所以也不能定义构造方法
  • 抽象类中可以定义静态代码块和动态代码块
  • 接口中不能定义代码块

三、接口的作用

1、使用接口作为能力的定义和规范。其中接口的定义代表某种能力,方法的定义代表规范。

2、在Java中只能单继承,但是有时候需要模拟多继承的效果,此时可以使用接口,因为接口可以实现多个。

3、接口可以实现多态效果。

四、接口的实现

使用implements关键字,在实现接口时,必须要重写接口中所有的方法,否则只能定义为抽象类。


public interface MyInterface {
    String name = "test";
    
    void say();
}

public class B implements MyInterface{
    @Override
    public void say() {
        System.out.println("say");
    }
}

public class TestMain {
    public static void main(String[] args) {
        MyInterface m = new B(); // 使用接口指向实现类的对象
        m.say();
    }
}

继承类的同时,实现多个接口:


public abstract class A {
    public abstract void hi();
}

public interface MyInterface2 {
    void a();
}
public class B extends A implements MyInterface, MyInterface2{
    @Override
    public void say() {
        System.out.println("say");
    }
​
    @Override
    public void a() {
        
    }
​
    @Override
    public void hi() {
        
    }
}

接口之间也可以继承,而且还可以多继承。


public interface A {
    void a();
}

public interface B {
    void b();
}

public interface C extends A, B{ // 接口的多继承
    void c();
}

public class D implements C{
    @Override
    public void a() {
    }
​
    @Override
    public void b() {
    }
​
    @Override
    public void c() {
    }
}

五、接口实现多态

可以通过接口引用实现类的对象,但是该对象只能调用接口中的方法。

案例:在一个好日子,进行飞行表演。

需要找具备飞行能力的对象来进行表演。


/**
 * 飞行能力
 */
public interface Fly {
    /**
     * 飞行
     */
    void fly(); 
}

public class GoodDay {
    public void show(Fly fly) {
        System.out.println("表演秀开始...");
        fly.fly();
    }
}

public class Bird implements Fly{
    @Override
    public void fly() {
        System.out.println("鸟在飞行表演...");
    }
}

public class Plane implements Fly{
    @Override
    public void fly() {
        System.out.println("飞机正在进行飞行表演...");
    }
}

public class Angel implements Fly{
    @Override
    public void fly() {
        System.out.println("召唤天使进行飞行表演..");
    }
}

public class TestMain {
    public static void main(String[] args) {
//      Fly fly = new Bird();
//      Fly fly = new Plane();
        Fly fly = new Angel();
        
        GoodDay day = new GoodDay();
        day.show(fly);
    }
}

六、常量接口

一个比较特殊的接口,主要是用来定义常量使用。

原因:每个类都可以定义常量,但是在接口中定义的变量默认为常量,比其他的类方便,而且不会出错,推荐在接口中定义项目所有的常量。


public interface Constants {
    int PAGE_SIZE = 5; // 每页显示5条数据
    String UPLOAD_FILE_BASE_PATH =  "D:\data\img\"; // 上传文件存放的目录
}

七、接口回调

回调:回头调用,使用接口实现,让方法执行完毕自动调用。

案例:

老师布置作业

学生完成作业

老师批改作业


public interface Callback {
    void piGai();
}

public class Student {
    public void wanCheng(Callback t) {
        System.out.println("学生写作业");
        System.out.println("学生写作业");
        System.out.println("学生写作业");
        System.out.println("学生完成作业");
        // 回调
        t.piGai();
    }
}

public class Teacher implements Callback{
    private Student student;
    
    public Teacher(Student student) {
        super();
        this.student = student;
    }
​
    public void buZhi() {
        System.out.println("老师布置作业");
        student.wanCheng(this);
    }
​
    public void piGai() {
        System.out.println("老师批改作业");
    }
}

public class TestMain {
    public static void main(String[] args) {
        Student s = new Student();
        Teacher t = new Teacher(s);
        
        t.buZhi();
    }
}

八、接口的好处

  • 解耦
  • 更自然的实现多态
  • 设计与实现分离