目录
一、接口的概念
定义了一套方法的声明的规范的结构称为接口
接口的作用:
- 补充java中单继承的不足之处,来模拟实现“多继承”。
- 规范一套方法的定义,以便实现多人协作。
二、接口的基本使用
接口的基本语法:
interface 接口名{
//可以定义属性
//可以声明方法
}
特点:
- 接口中所有定义的属性都默认为public static final,必须要赋值。
- 接口中所有声明的方法都默认为public static,此时可以省略。
- 接口不能直接创建对象使用。
- 接口中的方法都是抽象的,只能声明不能实现。
public interface A {
//接口中所有方法默认为public static,此时可以省略
//接口中的方法是抽象的,只能声明不能实现
void m1();
void m2();
//接口中定义的变量默认为public static final,必须要赋值
int COUNT = 5;
}
面试问题:接口和抽象类的区别:
相同点:1、可以声明抽象方法。2、不能直接创建对象
不同点:1、抽象类可以定义普通属性,接口中属性都是public static final。
2、抽象类可以声明普通方法,接口中方法都是public static。
3、抽象类可以有构造方法、代码块,接口中不能定义这些。
三、接口的实现
/*接口的实现,使用implements*/
public class B implements A{
@Override
public void m1() {
System.out.println("接口中的m1方法");
}
@Override
public void m2() {
System.out.println("接口中的m2方法");
}
//A接口中有两个方法,如果只在B中实现一个方法,则当前类必须是抽象类,即需要将B类定义为抽象类
}
四、使用接口实现多态
实例:找具有飞行能力的对象来进行飞行表演
/*定义接口*/
public interface Flyable {
void Fly();
}
/*定义具备飞行的能力的类*/
public class Bird implements Flyable{
@Override
public void Fly() {
System.out.println("鸟在飞");
}
}
public class Plane implements Flyable{
@Override
public void Fly() {
System.out.println("飞机在进行飞行表演");
}
}
public class Angle implements Flyable{
@Override
public void Fly() {
System.out.println("天使在进行飞行表演");
}
}
/*需要人去寻找飞行能力的对象*/
public class Person {
//在方法中使用参数类型是接口类型,表示只需要具备飞行能力的对象,都可以来进行飞行表演
public void doEvent(Flyable f){
f.Fly();
}
}
测试:
public class TestFly {
public static void main(String[] args) {
Person person = new Person();
Flyable f = new Plane();
Flyable b = new Bird();
Flyable a = new Angle();
person.doEvent(f);
person.doEvent(b);
person.doEvent(a);
}
}
结果:
五、继承类并实现多个接口
实例:狗继承动物类,并实现奔跑和游泳的接口
/*声明动物类*/
public abstract class Animal {
public abstract void eat();
public abstract void sleep();
}
/*声明跑的接口*/
public interface Runnable {
void run();
}
/*声明游泳的接口*/
public interface Swimmable {
void swim();
}
/*继承动物类并实现多个接口*/
public class Dog extends Animal implements Runnable,Swimmable{
@Override
public void swim() {
System.out.println("狗在游泳");
}
@Override
public void run() {
System.out.println("狗在跑");
}
@Override
public void eat() {
System.out.println("狗在吃");
}
@Override
public void sleep() {
System.out.println("狗在睡觉");
}
}
测试:
public class Test {
public static void main(String[] args) {
Animal animal = new Dog();
animal.eat();
animal.sleep();
Runnable r = new Dog();
r.run();
Swimmable s = new Dog();
s.swim();
}
}
结果:
六、接口的继承
接口可以继承其他接口,甚至可以继承多个接口。在实现该接口时,需要实现该接口中声明的所有方法。包括继承过来的方法。
public interface A {
//接口中所有方法默认为public static,此时可以省略
//接口中的方法是抽象的,只能声明不能实现
void m1();
void m2();
//接口中定义的变量默认为public static final,必须要赋值
int COUNT = 5;
}
public interface E{
void m4();
}
//继承多个接口
public interface C extends A,E{
void m3();
}
//接口的继承,并实现接口中所有声明的方法
public class D implements C{
@Override
public void m1() {
}
@Override
public void m2() {
}
@Override
public void m3() {
}
@Override
public void m4() {
}
}
七、常量接口
因为在接口中定义的所有变量自动被编译成public static final,即为常量。所以接口是定义常量的一个很好的地方。在项目中经常会把常量全部定义在一些接口中,这些接口中没有定义方法,被称为常量接口。
八、接口的回调
案例: 老师安排学生写作业。
学生写作业。
写完作业提交。
老师批改作业。
在此案例中,老师调用管理的学生的方法,在学生执行该方法的过程中,又需要调用老师的方法。此时就出现了回调。
如果在学生类中将回调的类型直接声明为老师,则无法实现多态,其他的非老师的对象无法安排学生写作业。
此时可以定义一个接口,在接口中声明一个回调的方法。所有实现该接口的类的对象都可以用来此处进行回调。
public interface Callback {
void checkHomework();
}
public class Teacher implements Callback{
//老师对象中有管理的学生属性
private Student student;
//通过构造方法设置学生属性
public Teacher(Student student){
this.student = student;
}
/*安排作业*/
public void doEvent(){
System.out.println("老师安排作业");
student.doHomework(this);
}
/*批改作业*/
@Override
public void checkHomework(){
System.out.println("老师批改作业");
}
}
public class Student {
public void doHomework(Callback t){
System.out.println("学生写作业");
System.out.println("学生提交作业");
t.checkHomework();
}
}
public class TestCallBack {
public static void main(String[] args) {
Student student = new Student();
Teacher teacher = new Teacher(student);
//老师布置作业
teacher.doEvent();
}
}
结果: