目录
概念
-
从功能上看, 实现接口就意味着扩展了某些功能
-
从规则上看, 接口定义者和接口实现者都必须满足指定规则
-
从抽象上看, 接口是特殊的抽象父类
接口的语法
访问修饰符 interface 接口名{ }
包: com.xxx.dao
接口的规则
-
属性都为公开静态常量(public static final)
-
修饰符固定, 所以可以省略或缺失,编译器会自动补全
-
-
方法都为公开抽象方法(public abstract)(JDK8.0之前版本)
-
修饰符也可省略或缺失
-
-
没有构造方法
-
无法实例化对象, 但是可以做引用声明
public interface IA { public static final int NUMBER = 100; int NUMBER2 = 200; // NUMBER2=300; public void ma(); }
实现类
实现了接口的类
访问修饰符 class 类名 implements 接口名1,接口名2,..{ }
包: com.xxx.dao.impl
规则
-
实现类必须重写接口中的抽象方法(推荐) , 除非实现类本身为抽象类(不推荐)
-
如果实现了多个接口,则需要对所有接口中的所有抽象方法提供方法重写
-
一个实现类可以实现多个接口, 一个接口也可以拥有多个实现类(多实现)
-
可以同时继承父类和实现接口, 先继承再实现
访问修饰符 class 类名 extends 父类类名 implements 接口名1,接口名2,..{}
-
仍然可以利用接口做引用声明创建实现类对象(多态)
接口名 引用名=new 实现类名();
-
接口(大)与实现类(小)之间的多态使用与父(大)子(小)类之间的多态使用完全一致
package com.by.dao; public interface IB { void mb(); }
package com.by.dao.impl; import com.by.dao.IA; import com.by.dao.IB; import com.by.entity.Super; public class Impl extends Super implements IA, IB { @Override public void ma() { System.out.println("Impl-ma"); } @Override public void mb() { System.out.println("Impl-mb"); } //独有内容 public void method(){ System.out.println("Impl的独有内容"); } }
package com.by.entity; public class Super { }
package com.by.test; import com.by.dao.IA; import com.by.dao.IB; import com.by.dao.impl.Impl; import com.by.entity.Super; public class Test { public static void main(String[] args) { // IA ia=new IA(); //多态创建实现类对象 IA ia = new Impl(); //1. 实际创建的为实现类对象 //2. 优先执行实现类内容 ia.ma(); //3. 接口引用无法访问实现类的独有内容 /* ia.mb(); ia.method(); 错误*/ //4. 多态前提下,想要访问独有内容,需要进行类型强转 Impl impl = (Impl) ia; impl.mb(); impl.method(); /*IB ib = (IB) ia; 也可转向其他 ib.mb();*/ //5. 接口和实现类之间也可以进行instanceof的判断 //5-1: 类型本身可以兼容 //5-2: 大类型可以兼容小类型对象 System.out.println(ia instanceof IA);//t System.out.println(ia instanceof Impl);//t System.out.println(ia instanceof IB);//t System.out.println(ia instanceof Super);//t } }
接口中的继承
一个接口可以继承多个父接口(多继承)
子接口可以继承拥有所有父接口中的内容(除私有方法外)
访问修饰符 interface 子接口名 extends 父接口名1,父接口名2,..{ }
接口和抽象类的区别
抽象类 | 接口 | |
---|---|---|
声明关键字 | abstract class | interface |
属性 | 不做要求 | 公开静态常量 |
方法 | 可以存在非抽象方法 | 公开抽象方法(JDK8.0前) |
构造 | 有 | 无 |
继承性 | 单继承 | 多继承 |
接口高级
高版本的接口
当父类内容与接口内容出现冲突时, 优先执行父类内容(类优先原则)
当接口与接口中的内容出现冲突时, 实现类必须对冲突方法再次重写,使用自身重写内容
JDK8.0
-
默认方法
default 返回值类型 方法名(形参列表){ //方法体 }
-
default不是访问修饰符, 作用为普通修饰符表示当前方法不为抽象方法
-
当前方法访问修饰符仍为public
-
普通的公开非抽象方法
-
实现类不需要对非抽象方法提供重写
-
-
静态方法
static 返回值类型 方法名(形参列表){ //方法体 }
-
公开的静态方法
-
可以直接通过
接口名.静态方法名(实参)
调用静态方法
-
JDK9.0
-
私有方法
private 返回值类型 方法名(形参列表){ //方法体 }
-
外界不可访问使用
-
接口回调
概念
先有接口的使用者,再有接口的实现者
好处
-
能够满足更多的开发场景(先知道功能, 后知道具体需求)
-
满足开发过程中的"开闭原则"
-
"开闭原则": 扩展开放,修改关闭
-
允许在现有代码的基础上扩展功能,但是不允许修改原有代码
-
-
本质为多态的第二个使用场景:先将方法参数声明为接口类型, 再根据需求定义实现类, 之后实参传入不同的实现类对象
-
比较器案例
Comparator: 比较器接口, 内置排序规则
步骤
-
创建一个Comparator的实现类, 重写compare方法
import java.util.Comparator; public class 实现类名 implements Comparator<被排序的类名> { @Override public int compare(被排序的类名 o1, 被排序的类名 o2) { return 0; } }
-
在compare方法中书写排序规则
-
从小到大:
-
o1的值>o2的值,返回正数
-
o1的值<o2的值,返回负数
-
-
从大到小:
-
o1的值>o2的值,返回负数
-
o1的值<o2的值,返回正数
-
-
值相等返回0
package com.by.dao.impl; import java.util.Comparator; import com.by.entity.Student; public class StudentComparator implements Comparator<Student> { @Override public int compare(Student o1, Student o2) { //根据成绩从小到大排序 if (o1.getScore() > o2.getScore()) { return 1; } else if (o1.getScore()<o2.getScore()) { return -1; } return 0; } }
-
-
使用实现类
-
java.util.Arrays.sort(被排序的数组名, Comparator实现类对象)
package com.by.test; import com.by.dao.impl.StudentComparator; import com.by.entity.Student; import java.util.Arrays; public class Test_comparator { public static void main(String[] args) { //学生对象数组 Student[] ss = {new Student("zhangsan", 20, 99.0), new Student("lisi", 23, 88.5), new Student("wangwu", 21, 90.0)}; //对数组排序-从小到大 Arrays.sort(ss,new StudentComparator()); for (int i = 0; i < ss.length; i++) { System.out.println(ss[i].getName()+" "+ss[i].getAge()+" "+ss[i].getScore()); } } }
-