一、接口的新特性

概述

jdk8之前接口是规则的集合体,方法只有抽象方法。

jdk8版本开始不仅有抽象方法同时增加了带实现的方法。

增加内容

jdk8: 默认方法 default

           静态方法 static

jdk9: 私有方法 private

二、默认方法

概述 :被关键字 default 修饰的方法就是默认方法,是在jdk8版本才出现的方法,独属于接口所有。

语法格式:修饰符 default 返回值类型 方法名 (参数列表){方法体}

使用规则:

1) 加上default的,实现类可以不重写,直接调用, 也可以重写.

2) 特殊情况1:实现类实现了两个接口,如果有相同的的默认方法声明,则强制要求在实现类中,重写 这个方法,以指定确定的实现内容.

3) 特殊情况2:在特殊情况1中,如果在实现类重写这个方法的过程中,希望指定其中第一个接口的默 认实现,则可以调用”父接口名.super.默认方法名称(实际参数)”

4) 特殊情况3:实现类继承了一个父类并且实现了一个接口,并且在父类中和接口中,有相同的方法声明,则“类优先”。即使用类的实现,即使继承的是一个抽象类,也是使用父类的实现(即强制重写)。

接口对抽象类的影响:

1、使接口拥有了具体的方法从而越来越接近抽象类

2、因为接口和类之间是:实现的关系,一个类可以实现多个接口,比抽象类更加容易使用,降低了耦合 性加强了扩展性,未来有取代抽象类的趋势。

3.所以有了默认方法,就会让大量的抽象类变成接口,即弱化了抽象类

public interface Inter1 {
public abstract void say();
// 默认方法
public default void eat() {
System.out.println("吃炸鸡...");
}
public default void sleep() {
System.out.println("Inter1_睡觉...");
}
}
public interface Inter2 {
public default void sleep() {
System.out.println("Inter2_睡席梦思...");
}
}
public class Person implements Inter1, Inter2{
@Override
public void say() {
System.out.println("你好....");
}
// 可以重写default修饰的方法,也可以不重写,不重写也不会报错
@Override
public void eat() {
System.out.println("吃汉堡...");
}
// 实现类实现了两个接口,如果有相同的的默认方法声明,则强制要求在实现类中,重写这个方
法,以指定确定的实现内容
@Override
public void sleep() {
// 想保留Inter1接口sleep方法的实现
Inter1.super.sleep();
// 还想保留Inter2接口sleep方法的实现
Inter2.super.sleep();
System.out.println("Person_睡沙发...");
}
}
// 父类
public class Fu {
public void sleep() {
System.out.println("Fu_睡小三....");
}
}
// 父类是普通类,与接口中defalut方法同名,不需要重写
public class Zi extends Fu implements Inter2{
}
// 抽象父类
public abstract class Fu2 {
public abstract void sleep();
}
// 父类是抽象类,与接口中default同名方法必须重写
public class Zi2 extends Fu2 implements Inter2{
@Override
public void sleep() {
System.out.println("Zi2_睡小七...");
}
}
// 接口中的默认方法
public class InterfaceDefalutMethod {
public static void main(String[] args) {
Person p = new Person();
p.say();
p.eat(); // default修饰的方法
p.sleep();
// 使用Zi类型
Zi z = new Zi();
z.sleep(); // 类优先原则,走的父类的实现
Zi2 z2 = new Zi2();
z2.sleep();
}
}

三、静态方法

概述:
静态方法独属于接口本身,实现类对象没有访问的权利,只能接口名调用方法。
使用:
1、直接使用接口名调用。
2、不同的接口中可以定义相同方法声明的静态方法,互不影响。
结论:
1、接口中的静态方法只能接口名调用,实现类对象没有权利使用。

2、静态方法提供给接口的默认方法使用。

// 使用接口中静态方法
public class UseInterfaceStaticMethod {
public static void main(String[] args) {
// 接口静态方法,只能接口调用
Inter1.show();
Inter2.show();
// 接口的实现类对象不能访问接口中的静态方法的
// new Dog().show();
new Dog().use();
}
}
interface Inter1 {
public default void use() {
System.out.println("Inter1...use");
show(); // default修饰方法可以使用static修饰方法
}
public static void show() {
// use(); 静态方法中不能访问default修饰的方法
System.out.println("Inter1...show");
}
}
interface Inter2 {
public static void show() {
System.out.println("Inter2...show");
}
}
class Dog implements Inter1, Inter2{
}

四、私有方法

概述:
修改项目汇依赖的jdk版本,目前使用时jdk8,无法使用jdk9中特有的语法,我们jdk都是高版本兼容低版本的。
我们使用jdk11.一样学习jdk9中特有的内容。
是jdk9版本增加的一个实体方法,主要是用来进一步封装代码,提升相关代码安全性的手段。私有化之后方法不能被实现类直接调用使用或重写修改,只能提供给接口的静态方法和默认方法使用。

使用:普通私有方法:只能提供给默认方法调用使用静态私有方法:默认方法和静态方法都可以调用。

public class InterfacePrivateMethod {
public static void main(String[] args) {
// 创建一个实现类对象
Student s = new Student();
// s.eat(); 实现类不能使用接口中私有方法
s.use();
}
}
interface Inter1 {
public default void use() {
System.out.println("使用工具");
// 可以在default修饰方法中使用
eat();
// 可以在defalut使用静态私有方法
sleep();
}
public static void show() {
System.out.println("一朵梨花压海棠");
// 静态方法不能使用普通私有方法
// eat();
// 静态方法可以使用静态私有方法
sleep();
}
// 普通私有方法
private void eat() {
System.out.println("私有的吃方法");
}
// 静态私有方法
private static void sleep() {
System.out.println("静态私有方法睡觉");
}
}
// 实现类
class Student implements Inter1 {
}

接口中内容总结:

1.抽象方法

2.默认方法

3.静态方法

4.私有方法

5.静态常量

五、函数式接口

1、Lambda表达式使用的前提,就是接口必须是一个函数式接口。

2、定义: 如果在接口中,有且仅有一个抽象方法,那么这个接口就是函数式接口

3、格式说明: 使用注解来检查当前接口是否是一个函数式接口 @FunctionalInterface 如果不是函数式接口,则编译报错

4、理解:

函数:想表达的是一个方法的内容,由于方法不在任何类中,所以称为函数, 这是C语言中的概念。(C语言中方法叫做函数)

函数式接口:其实想表达的就是一个函数(方法)的声明

5、作用: 使用函数式接口表达函数[方法]的声明;使用函数式接口的实现类对象表达函数(方法)的实现, 函数式接口做到一点:方法和类型是一对一的关系.

6、使用原因: Java中不支持将方法作为一个数据,也就不能将这个方法进行各种传递,也就不能作为对象的成员 变量存在,只能在方法外加一层接口的声明,将来可以传递方法所在接口的实现类对象,来间接的传递方 法内容

7、总结: 方法在Java中不能作为一种数据类型存在, 只是功能, 因此将方法称为函数; 有些场景下, 需要将方法作为参数传递的, 所以将这个方法封装在一个接口中, 而这个接口的存在就是为了方法穿上 一件外衣, 需要方法场景下, 可以直接传递这个函数式接口, 相当于传递其中唯一的抽象方法. 举例 : 客户,要求定义出一个方法功能, 对两个整数进行任意,既要穿两个整数,还要能传递操作的两个整数功能进去.

1) 两数求和

2) 两数求差

3) 两数乘积 * 2

4) ... 无数需求, 都需要在同一个方法中完成

public int useTwoInt(int x, int y, 对于x和y两数的操作思想 , 操作方式 ) {

}

// 函数式接口好处
public class GoodOfFuncationalInterface {
public static void main(String[] args) {
// 要求两个整数的和
int r = useTwoInt(10, 20, new UseNumber() {
@Override
public int useNumber(int a, int b) {
return a + b;
}
});
System.out.println(r);
//求a的b次方, 不仅仅能传递数据进入方法useTwoInt,还能传递功能(数据的操作方式)进
入方法useTwoInt.
// 这里接口的匿名内部类就是功能
r = useTwoInt(2, 3, new UseNumber() {
@Override
public int useNumber(int a, int b) {
return (int)Math.pow(a, b);
}
});
System.out.println(r);
// 求a*b两倍
r = useTwoInt(3, 4, new UseNumber() {
@Override
public int useNumber(int a, int b) {
return a * b * 2;
}
});
System.out.println(r);
}
// 客户,要求定义出一个方法功能, 对两个整数进行任意,既要穿两个整数,还要能传递操作的两
个整数功能进去.
/*
// 1) 两数求和
public static int useTwoInt1(int a, int b) {
return a + b;
}
// 2) 两数求差
public static int useTwoInt2(int a, int b) {
return a - b;
}
// 3) 两数乘积 * 2
public static int useTwoInt3(int a, int b) {
return a * b * 2;
}
// 4) ... 无数需求, 都需要在同一个方法中完成
*/
public static int useTwoInt(int a, int b, UseNumber un) {
return un.useNumber(a, b);
}
}
@FunctionalInterface
interface UseNumber {
public abstract int useNumber(int a, int b);
}

Lambda表达式

概述:
1.Lambda表达式是java对函数接口表达式的一种体现形式,本质是一个值,在java中主要是体现在对特殊的匿名内部类对象的一种表示,代表匿名内部类的对象。
2.简单理解: Lambda表达式是对接口匿名内部类格式的一种简化,但是本质不一样。
3.都是匿名内部类对象但是一个是进行单独编译,创建的对象,Lambda表达式不会单独编译,本质是值.值表示了匿名内部类的对象.
●前提:⭐⭐⭐
1、有且只有一个抽象方法的接口,函数式接口
2、必须要由上下文推断,根据接口中抽象方法进行1ambda表达式的书写.
●格式:⭐⭐⭐

1.标准格式:【三个一:一个小括号 一个箭头 一个花括号】 (参数列表)->{执行代码段}

2.格式解释:

(参数列表):里面写实现的函数式接口中的抽象的参数.【就是接口抽象方法的参数列表】

->:原封不动 他是lambda表达式的标志,Lambda运算符,也可以叫"箭头运算符"

{执行代码段}:lambda表达式对接口抽象方法的重写, 相当于之前重写抽象的方法体. 也称之为 lambda体.

3.语法格式1, 接口中抽象方法: 没有参数,没有返回值抽象方法

()->System.out.println(“Hello Lambda”);

注意:没有参数小括号不能省略

4.语法格式2,接口中抽象方法:有一个参数,没有返回值

x->System.out.println(“你好 ”+x);

注意: 如果只有一个参数, 小括号可以省略

5. 语法格式3,接口中抽象方法: 有多个参数, 没有返回值

(x, y)->System.out.println(x+y);

6. 语法格式4,接口中抽象方法: 无参数, 有返回值

()->{return 10;}

注意:如果Lambda表示只有一条语句,大括号可以省略不写; 但是方法体中只有一个return语句,如果 想省略大括号,必须把return去掉, 否则不能省略大括号

7. 语法格式5, 接口中抽象方法:有多个参数, 方法体中多条语句, 不能省略大括号.

(x, y)->{double pow = Math.pow(x, y); return pow};

注意:如果Lambda表示只有一条语句,大括号可以省略不写; 但是方法体中只有一个return语句.,如果 想省略大括号,必须把return去掉, 否则不能省略大括号. (x,y)->Math.pow(x,y);

结论:

lambda表示式就是得到函数式接口实现类对象的另一种体现.

函数式接口实现方式有: 1、定义实现类创建对象 2、 匿名内部类 3、lambda表达式

public class UseLambda {
public static void main(String[] args) {
// 使用匿名内部类为Inter1提供一个实现类对象
/* new Inter1() {
@Override
public void eat() {
System.out.println("吃炸鸡喝啤酒");
}
};
()-> System.out.println("吃炸鸡喝啤酒");*/
Inter1 imp1 = new Inter1() {
@Override
public void eat() {
System.out.println("吃炸鸡喝啤酒");
}
};
imp1.eat();
// lambda就是为了简化函数式接口匿名内部类实现而设计的.
Inter1 imp2 = ()-> { System.out.println("吃炸鸡喝啤酒"); };
imp2.eat();
// 非函数式接口只能使用匿名内部类的方式提供实现
Inter2 imp3 = new Inter2() {
@Override
public void show() {
System.out.println("你好");
}
@Override
public void use() {
}
};
// 接口不是函数式接口无法使用lambda简化匿名内部类的实现
// Inter2 imp4 = () -> System.out.println("你好")
}
}
@FunctionalInterface
interface Inter1 {
public abstract void eat();
}
interface Inter2 {
public abstract void show();
public abstract void use();
}
public class UseLambda2 {
public static void main(String[] args) {
// Inter3中抽象方法,无参无返
Inter3 imp1 = ()->{
System.out.println("吃炸鸡");
};
imp1.eat();// 直接调用接口中的抽象方法
// lamdba体中只有一条语句,可以省略大括号
Inter3 imp2 = () -> System.out.println("吃烤串串");
imp2.eat();
// lamdba体中有多条语句,大括号不能省略
Inter3 imp3 = ()-> {
System.out.println("吃火锅"); // 省略之后,只有第一条语句属于lambda表达
式
System.out.println("吃生蚝");
System.out.println("吃鲍鱼");
};
imp3.eat();
imp3.eat();
}
}
@FunctionalInterface
interface Inter3 {
public abstract void eat();
}
package com.ujiuye.demo07;
public class UseLambda3 {
public static void main(String[] args) {
// Inter4使用Lambda提供实现类对象
Inter4 imp1 = (String msg) -> {
System.out.println(msg);
};
imp1.show("祥哥最帅");
// lamdba表达式中参数列表部分可以省略参数的数据类型
Inter4 imp2 = (msg)-> System.out.println(msg);
imp2.show("翔是神");
// lamdba表达式中参数只有一个的时候,可以省略小括号
Inter4 imp3 = msg-> System.out.println(msg);
imp3.show("毅少很快");
}
}
@FunctionalInterface
interface Inter4 {
// 有一个参数,没有返回值的抽象方法
public abstract void show(String msg);
}
package com.ujiuye.demo07;
public class UseLambda4 {
public static void main(String[] args) {
// Inter5使用lambda表达式提供实现类对象
Inter5 imp1 = (int a, int b)->{
System.out.println(a + b);
};
imp1.sum(10, 20);
// lamdba都可以不写参数的数据类型
Inter5 imp2 = (a, b) -> System.out.println(a + b);
imp2.sum(30, 40);
// 多个参数不能省略小括号
/*Inter5 imp3 = a, b -> System.out.println(a + b);
imp3.sum(30, 40);*/
// lambda表示中:参数名可以自定义
Inter5 imp4 = (x, y) -> System.out.println(x - y);
imp4.sum(30, 40);
}
}
@FunctionalInterface
interface Inter5 {
// 有个多个参数,没有返回值
public abstract void sum(int a, int b);
}
package com.ujiuye.demo07;
public class UseLambda5 {
public static void main(String[] args) {
// Inter6使用lambda提供实现类对象
Inter6 imp1 = () -> {
String name = "李四";
return name; // 抽象方法的返回值是什么类型数据, lambda体中return后就要
跟什么类型数据
};
String name = imp1.getName();
System.out.println(name);
// 如果lambda体中只有一个语句, return语句,
// 大括号可以省略,但是必须也把return关键字省略掉
/*
Inter6 imp2 = ()-> {
return "王五";
};
*/
Inter6 imp2 = ()-> "王五";
System.out.println(imp2.getName());
}
}
@FunctionalInterface
interface Inter6 {
public abstract String getName();
}
package com.ujiuye.demo07;
public class UseLambda6 {
public static void main(String[] args) {
// Inter7通过lambda表达式提供实现类对象
Inter7 imp1 = (int a, int b)->{
return a + b;
};
System.out.println(imp1.useNumber(10, 20));
// 简化
Inter7 imp2 = (a, b)-> a + b;
System.out.println(imp2.useNumber(10, 20));
Inter7 imp3 = (x, y)->{
double d = Math.pow(x, y);
return (int)d;
};
System.out.println(imp3.useNumber(3, 3));
// 简化
Inter7 imp4 = (x, y)->(int)Math.pow(x, y);
System.out.println(imp3.useNumber(3, 3));
}
}
@FunctionalInterface
interface Inter7 {
public abstract int useNumber(int a, int b);
}
@FunctionalInterface
public interface USB {
public abstract void powOn();
}
// 定义一个类实现
public class Mouse implements USB{
@Override
public void powOn() {
System.out.println("鼠标通电");
}
}
public class UseUSb {
public static void main(String[] args) {
// 匿名内部类实现
new USB(){
@Override
public void powOn() {
System.out.println("测试设备通电");
}
}.powOn();
// lambda实现
USB usb = ()->{
System.out.println("");
};
}
}

Lambda表达式的省略原则总结

概述:在符合一定条件下Lambda表达式的格式可以进行简化的 标准的lambda表达式

具体原则:

1、小括号参数的参数类型可以直接省略

2、小括号的参数有且只有一个的时候,小括号可以省略

3、大括号中有且只有一个执行语句的时候,可以同时省略花括号 分号 和 return关键字 【要省略三者同时省略,否则一个都不要省略】

4、小括号和花括号的省略原则互不干扰,各省略各的

方法引用

 概述:方法引用是对函数式接口的实现类对象获取的另一种方式,可以理解为是lambda表达式的栾生兄弟 都是用来体现特殊接口[函数式接口]的实现类读写的新方式。 如果咱们发现一个函数式接口的实现方法,也就是抽象方法的重写,发现已经在其他类中有相同格式成员 方法,或者静态方法的时候,那么我们就不用使用lambda表示实现了,直接引用其他类中的成员方法或者 静态方法.这就叫做方法的引用.

特殊条件:Lambda表达式是对接口抽象方法重写的方法体,在其他类中有具体的方法已经书写实现过的情况就可以 使用方法引用表示接口的实现类对象 使用范围比lambda更小了。 lambda表达式适用于所有的有且只有一个抽象方法的接口,函数式接口 方法引用只能使用于有且只有一个抽象方法的接口的部分接口

使用前提:1、必须是是一个函数式接口 2、必须有上下文推断, 抽象方法无返回值的情况:只推断函数式接口中抽象方法参数部分和要引用的方法参数部分是否一致. 抽象方法有返回值的情况:引用的方法参数列表要一致,返回值类型也要一致.

方法引用的格式:

静态方法引用:

类名 ::静态方法名

成员方法引用:

对象名 ::普通方法名

构造方法的引用:

类名 ::new

JDK8和JDK9【新特性】相关推荐

  1. JDK8与JDK9新特性学习

    一.环境和软件准备 环境:window或者linux环境 下载软件: 1.JDK版本:JDK9下载路径 2.安装eclipse,当然可以使用其他编辑器 二.Lambda表达式预演 1.面向对象的Run ...

  2. JDK9新特性实战:简化流关闭新姿势

    转载自 JDK9新特性实战:简化流关闭新姿势. 做Java开发的都知道,每个资源的打开都需要对应的关闭操作,不然就会使资源一直占用而造成资源浪费,从而降低系统性能. 关于资源的关闭操作,从JDK7-J ...

  3. JDK8升至JDK11 新特性整理

    目录 方法新增/修改 String CharSequence Character Path Files Reader Writer InputStream OutputStream Predicate ...

  4. JDK9 新特性详解

    1.Java9 新特性之目录结构 包含 jdk8 及以前的 jdk 版本,所有目录结构以及目录含义如图: jdk9 之后,目录结构发生变化如图: 这个新特性只要了解下就可以了,这个目录结构是方便为了接 ...

  5. JDK9新特性实战:简化流关闭新姿势。

    image 做Java开发的都知道,每个资源的打开都需要对应的关闭操作,不然就会使资源一直占用而造成资源浪费,从而降低系统性能. 关于资源的关闭操作,从JDK7-JDK9有了不少的提升及简化. JDK ...

  6. JDK8中的新特性——函数式接口

    JDK8 简介 概述 Java 8由Oracle从2014年3月18日发布,此版本是自Java 5(发布于2004年)之后的一个重量级版本,也是java发展史上的一个里程碑式的版本.这个版本在JVM. ...

  7. JDK8 十大新特性详解

    本教程将Java8的新特新逐一列出,并将使用简单的代码示例来指导你如何使用默认接口方法,lambda表达式,方法引用以及多重Annotation,之后你将会学到最新的API上的改进,比如流,函数式接口 ...

  8. JDK8 十大新特性详解(发现面试官挺喜欢问的)

    本教程将Java8的新特新逐一列出,并将使用简单的代码示例来指导你如何使用默认接口方法,lambda表达式,方法引用以及多重Annotation,之后你将会学到最新的API上的改进,比如流,函数式接口 ...

  9. jdk8新特性_JDK8与JDK9新特性学习

    一.环境和软件准备 环境:window或者linux环境 下载软件: 1.JDK版本:JDK9下载路径 2.安装eclipse,当然可以使用其他编辑器 二.Lambda表达式预演 1.面向对象的Run ...

  10. JDK8之Stream新特性

    /***JDK8 Stream特性* Created by chengbx on 2018/5/27.* Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集 ...

最新文章

  1. 再见,Teamviewer!这款国产轻量级远程桌面软件超牛逼!
  2. 上拉电阻与下拉电阻的作用
  3. Vue的自定义滚动,我用el-scrollbar
  4. Kubernetes1.5新特性(一):Kubelet API增加认证和授权能力
  5. PostgreSQL(一)PostgreSQL一主二从集群部署
  6. 运行mysql时,提示Table ‘performance_schema.session_variables’ doesn’t exist
  7. VS2015+OpenCV2.4.13环境搭建详细步骤及自带示例编译运行
  8. 「Python」 ElementTree模块解析xml文件,建议小白阅读全文
  9. 使用squid代理时出现“The requested URL could not be retrieved”
  10. 解决MySQL报错... right syntax to use near ‘password ‘XXX‘ at line 1...ERROR 1064 42000: You have an erro
  11. 还在用 Win?教你从零把 Mac 打造成开发利器
  12. 电力物联网智慧路灯充电桩传感器技术应用方案
  13. maven的pom.xml文件
  14. AI学习笔记(二)图像与视频
  15. 解决微信小程序使用switchTab跳转后页面不刷新的问题
  16. 基于Swing与JavaFx的音乐播放器——轻音
  17. java 数据 excel模板_java导出excel模板数据
  18. oss 私有云访问 获取临时图片地址
  19. 数据结构队列的代码实现
  20. Eclipse Mars2中Augular2开发环境的搭建过程记录

热门文章

  1. Address already in use: bind
  2. 查看linux的系统信息
  3. 招聘网python职位_Python+selenium爬取智联招聘的职位信息
  4. 模拟经营动物园java,动物园游戏下载|动物园下载 (经典模拟经营游戏)_单机游戏下载...
  5. 2016杭州云栖大会10月开幕 规模翻倍
  6. CVBS全电视信号的一些基本知识
  7. Chrome 浏览器如何修改 User-Agent
  8. 计算平均成绩(PTA)
  9. 哈尔滨工程大学考研经验分享(下):复试
  10. java poi2007_Java使用POI读取2007+版本PPT