接口
一、接口的基本使用
接口的基本语法:
interface 名称{
// 可以定义属性
// 可以声明方法
}
- 接口中所有的属性皆为publi static final的
- 接口中所有的方法声明皆为public abstract
- 接口不能直接创建对象使用
public interface A {
public static final int COUNT = 5; // 接口中定义的变量默认为public static final,必须要赋值
public abstract void m1(); // 所有在接口中定义的方法自动为公有、抽象
void m2();
}
面试问题:接口和抽象类的区别:
相同点:1、可以声明抽象方法。2、不能直接创建对象
区别:
1、抽象类可以定义普通的属性。接口中所有属性皆为public static final。
2、抽象类可以定义普通的方法。接口中只能声明方法,而不能实现。
3、抽象类可以有构造方法、代码块。接口不能定义这些。
二、接口的概念
定义了一套方法的声明的规范的结构称为接口。
接口的作用:
1、补充Java中单继承的不足之处,来模拟实现“多继承”。
2、规范一套方法的定义,以便实现多人协作。
三、接口的实现
public class B implements A{
@Override
public void m1() {
System.out.println("m1");
}
@Override
public void m2() {
System.out.println("m2");
}
}
四、使用接口实现多态
示例:找到具有飞行能力的对象来进行飞行表演。
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 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();
person.doEvent(f);
}
}
五、继承类并实现多个接口
狗类继承了动物类,实现了奔跑、游泳接口
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 TestAnimal {
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 abstract void m1(); // 所有在接口中定义的方法自动为公有、抽象
void m2();
}
public interface E {
void m4();
void m1();
}
public interface C extends A, E{
void m3();
}
public class D implements C{
// 需要实现m1、m2、m3、m4方法。
}
七、常量接口
因为在接口中定义的所有变量自动被编译成public static final,即为常量。所以接口是定义常量的一个很好的地方。在项目中经常会把常量全部定义在一些接口中,这些接口中没有定义方法,被称为常量接口。
八、接口中方法实现的特例
- 接口中可以实现静态方法,使用接口名调用
- 接口中可以实现默认方法,在实现类中可以不用再次重写该方法。
public interface MyInterface {
static void m1() {
System.out.println("接口中的静态方法实现...");
}
default void m2(){
System.out.println("m2方法的默认实现");
}
void m3();
}
public class MyImpl implements MyInterface{
@Override
public void m3() {
System.out.println("m3方法的实现");
}
// 可以不重写此方法
@Override
public void m2() {
// TODO Auto-generated method stub
// MyInterface.super.m2();
System.out.println("m2重写之后的实现");
}
}
public class Test1 {
public static void main(String[] args) {
MyInterface.m1();
MyImpl m = new MyImpl();
m.m2();
}
}
九、接口回调
案例:
老师安排学生写作业。
学生写作业。
写完作业提交。
老师批改作业。
在此案例中,老师调用管理的学生的方法,在学生执行该方法的过程中,又需要调用老师的方法。此时就出现了回调。
如果在学生类中将回调的类型直接声明为老师,则无法实现多态,其他的非老师的对象无法安排学生写作业。
此时可以定义一个接口,在接口中声明一个回调的方法。所有实现该接口的类的对象都可以用来此处进行回调。
public class Student {
public void doHomework(Callback t) {
System.out.println("学生写作业");
// try {
// Thread.sleep(5000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
System.out.println("学生提交作业");
t.accept();
}
}
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 accept() {
System.out.println("老师批改作业");
}
}
public interface Callback {
void accept();
}
public class Parent implements Callback{
private Student student;
public Parent(Student student) {
super();
this.student = student;
}
public void doEvent() {
System.out.println("家长安排学生写作业");
student.doHomework(this);
}
@Override
public void accept() {
System.out.println("家长批改作业");
}
}
public class TestCallBack {
public static void main(String[] args) {
// 1. 老师布置作业
// 2. 学生写作业,写完提交
// 3. 老师批改作业
Student student = new Student();
Teacher teacher = new Teacher(student);
// 1. 老师布置作业
teacher.doEvent();
// 创建家长
Parent parent = new Parent(student);
// 1. 家长布置作业
parent.doEvent();
}
}