接口,向下造型,Lambda(函数式接口)
接口:
抽象类中所有的方法都是抽象方法,然后就可以把这个类提升为接口,用interface来表示,接口不是类(但编译生成的依然是class文件)
接口的优点:模板,约束
类与接口之间通过implements 让两者之间产生关联关系:实现(类与接口之间支持多实现)
接口与接口之间支持多继承(提高代码复用性,得到更多的抽象方法)
普通类实现了接口,就要重写所有的抽象方法,如果不想重写,就要变成抽象类
问题:
接口可以创建对象吗? 不能定义构造方法,所以创建不了对象
接口中都是抽象方法? 不一定,jdk1.8之前结论正确,jdk1.8开始,java支持接口中定义实体方法
示例:
import java.awt.Shape; import java.io.Serializable; public class Text { public static void main(String[] args) { } } //interface 表示接口,不是类 编译完成之后任然是.class文件 //接口与接口之间支持多继承(提高代码复用性,可以拿带更多的抽象方法) interface Sharp extends Cloneable,Serializable{ public abstract double getGirth(); public abstract double getArea(); } //implements -----------表示类与接口之间的关联关系:实现 多实现 //extends 可以与implements 一起使用,extends 需要放在 implements 前 //普通类实现了一个接口,就要重写所有的抽象方法 //如果不想重写所有抽象方法,就要把类变成抽象类 class Rectangle extends Text implements Sharp,Cloneable{ @Override public double getGirth() { return 0; } @Override public double getArea() { return 0; } }
向下造型:可以调到子类的所有信息------依赖向上造型
接口在编译时期可以接住所有类型对象的强转
public class Text { public static void main(String[] args) { //向上造型 B b = new C(); //向下造型 //编译运行没错 //在编译时期,java对应对象转类型会检测两个对象的声明类,是否有继承关系 //b对象的声明类是B,c对象的声明类是C,有继承关系编译通过 //在运行时期java会去检测两个对象的实际创建类是否是一个类 //c对象的实际创建类是C类,b的实际创建类是C类,一致运行通过 C c = (C)b; //java.lang.ClassCastException类型转换异常,编译没错,运行出错 //d对象的实际创建类是D,b的实际创建类是C类,不一致,与运行不通过 // D d =(D)b; //编译报错 //d1的声明类是D类,c对象的声明类是C类,没有继承关系,编译不通过 // D d1 =(D)c; System.out.println(c.i); //类与类之间是单继承关系,可以快速检测类与类之间的关系,所以在编译时期才会去检测 //接口与接口之间是多继承,类与接口之间是多实现,是网状结构,不能快速检测之间的关系,所以放在运行时期检测 //运行时期检测,会检测对象的实际创建类与接口是否有实现关系 A a = (A)b; A a1 = (A)c; } } interface A{ } class B implements A{} class C extends B{ int i=2; } class D extends B{}
自己对向下造型的理解
public class Text { public static void main(String[] args) { //向上造型 B b = new C(); //向下造型,C为B的子类,可以被转化 C c = (C)b; c.syso(); //D非C的子类,所以不能被转化,编译时报错 // D d = new D(); // C C1 = (C)d; // //有继承关系,但是调用的构造方法不一样,运行时报错 D d =(D)b; } } class B{ private int i=1; } class C extends B{ public void syso() { System.out.print("这里是C类"); } } class D extends B{ }
接口中可以定义属性吗
接口中可以定义属性:默认被public ,static ,private共同修饰
在定义抽象方法的时候,默认被public ,abstract 共同修饰
jdk1.8在接口中出现的新特性
1.接口中允许定义实体方法(static ,default)
函数式接口------接口中只有一个抽象方法—--可以用@FunctionalInterface标注
Lambda表达式-------重写接口中的抽象方法-----接口中有且仅当只有一个抽象方法可以使用
public class Text { public static void main(String[] args) { //Lambda表达式------------------接口中有且仅当只有一个抽象方法 //(参数列表)->{重写方法的方法体}; Calc c=(int n,int m)->{return n>m?n:m;}; System.out.println(c.sum(4, 5)); //如果重写的方法体只有一句话,可以省略大括号以及return不写 Calc c1=(int n,int m)->n>m?n:m; System.out.println(c1.sum(4, 5)); //因为接口中的参数列表已经检测,就可以往后推导出参数列表的类型 //后面就可以省略类型不写 Calc c2=(n,m)->n>m?n:m; System.out.println(c1.sum(4, 5)); } } //计算器 interface Calc{ //相加功能 //default修饰的方法就是实体方法 public default int sum(int n,int m) { return n+m; } //相除功能 //static修饰接口中的方法成了实体方法 public static int cj(int n,int m){ return n*m; } //比大小 int max(int m,int n); }
数组形式:最简形式
import java.util.Arrays; public class Text { public static void main(String[] args) { int[] a={1,2,3,1}; //重写方法 Array s = (int[] a1)->{Arrays.sort(a1);}; //调用方法---排序 // s.sortAttay(a); // System.out.println(Arrays.toString(a)); // // //排序 // //输出类型可以从前往后推导出来,就可以不写 // //一个参数的时候()也可以省略 // Array s1 = arr1->Arrays.sort(arr1); // //输出 // System.out.println(Arrays.toString(a)); // //::表示传递的是静态方法 //s2的数据参数与静态方法中的参数一致 Array s2=Arrays::sort; //排序 s2.sortAttay(a); //输出 System.out.println(Arrays.toString(a)); } } interface Array{ //排序 void sortAttay(int[] arr); }
保存redis相关笔记