接口,向下造型,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);
}

 

posted @ 2020-08-18 20:34  minnersun  阅读(162)  评论(0编辑  收藏  举报