接口组成更新
1. 概述
接口组成:
- 常量
public static final
(可以省略) - 抽象方法
public abstract
- 默认方法(java8)
- 静态方法(java8)
- 私有方法(java9)
2. 接口中默认方法
案例: public default void show()
注意事项:
- 默认方法不是抽象方法,所以不强制重写;但也可以被重写,重写的时候去掉关键字default关键字
- public可以省略,default不可以被省略
package Lambda;
//接口
public interface Interface {
void show1();
void show2();
//show3也可以被重写
default void show3() {
System.out.println("show3万岁");
}
}
package Lambda;
//实现接口的类
public class InterfaceImpl implements Interface {
@Override
public void show1() {
System.out.println("one show1");
}
@Override
public void show2() {
System.out.println("one show2");
}
}
package Lambda;
/*测试类*/
public class Demo {
public static void main(String[] args) {
Interface s1 = new InterfaceImpl();
s1.show1();
s1.show2();
s1.show3();
//one show1
//one show2
//show3万岁
}
}
3. 接口中静态方法
格式案例:public static void show()
注意事项:
- 静态方法只能通过接口名调用,不能通过实现类或者对象名调用
- public可以省略,static不能省略
package Lambda;
//接口
public interface Interface {
void show1();
default void show2() {
System.out.println("默认方法被调用");
}
static void show3() {
System.out.println("静态方法被调用");
}
}
package Lambda;
//实现接口的类
public class InterfaceImpl implements Interface {
@Override
public void show1() {
System.out.println("抽象方法被调用");
}
}
package Lambda;
/*测试类*/
public class Demo {
public static void main(String[] args) {
Interface s1 = new InterfaceImpl();
s1.show1();
s1.show2();
Interface.show3();
}
}
4. 接口中私有方法
定义格式案例:
private void show()
private static void show()
注意事项:
- 默认方法可以调用私有静态和非静态方法
- 静态方法只能调用静态方法
package Lambda;
//接口
public interface Interface {
//默认
default void show1() {
System.out.println("默认方法show1 开始");
show();
System.out.println("默认方法show1 结束");
}
default void show2() {
System.out.println("默认方法show2 开始");
show();
System.out.println("默认方法show2 结束");
}
//私有方法
private void show() {
System.out.println("初级工程师");
System.out.println("中级工程师");
System.out.println("高级工程师");
}
//静态
static void method1() {
System.out.println("静态方法method1 开始");
method();
System.out.println("静态方法method1 结束");
}
static void method2() {
System.out.println("静态方法method2 开始");
method();
System.out.println("静态方法method2 结束");
}
//私有静态方法
private static void method() {
System.out.println("初级工程师");
System.out.println("中级工程师");
System.out.println("高级工程师");
}
}
package Lambda;
//实现接口的类
public class InterfaceImpl implements Interface {
}
package Lambda;
/*测试类*/
public class Demo {
public static void main(String[] args) {
Interface s = new InterfaceImpl();
s.show1();
System.out.println("******************");
s.show2();
System.out.println("******************");
Interface.method1();
System.out.println("******************");
Interface.method2();
//默认方法show1 开始
//初级工程师
//中级工程师
//高级工程师
//默认方法show1 结束
//******************
//默认方法show2 开始
//初级工程师
//中级工程师
//高级工程师
//默认方法show2 结束
//******************
//静态方法method1 开始
//初级工程师
//中级工程师
//高级工程师
//静态方法method1 结束
//******************
//静态方法method2 开始
//初级工程师
//中级工程师
//高级工程师
//静态方法method2 结束
}
}
方法引用
1. 方法应用符
- :: 该符号是引用运算符,它所在的表达式被称为方法的应用
推到和省略:md这个自动推导就很迷
- 如果使用Lambda,那么根据“可推导就是可省略”的原则,无需指定参数类型,也无需指定的重载形式,它们都将被自动推导
- 如果使用方法引用,也是同样可以根据上下文进行推导
- 方法引用是Lambda的孪生兄弟
package Lambda;
//接口
public interface Interface {
void show(int x);
}
package Lambda;
/*测试类*/
public class Demo {
public static void main(String[] args) {
useInterface(x -> System.out.println(x));//100
useInterface(System.out::println);//100
}
public static void useInterface(Interface i){
i.show(100);
}
}
2. Lambda支持的方法引用(常见版)
常见的引用方式:
- 引用类方法
- 引用对象的实例方法
- 引用类的实例方法
- 引用构造器
2.1 引用类方法
格式:类名::静态方法
package Lambda;
//接口
public interface Interface {
int convert(String s);
}
package Lambda;
/*测试类*/
public class Demo {
public static void main(String[] args) {
useInterface(s -> Integer.parseInt(s));//666
//引用方法
useInterface(Integer::parseInt);//666
//Lambda表达式被类方法替代后,他的形参(这里是s)全部传递给静态方法作为参数(给了parseInt)
}
public static void useInterface(Interface i) {
int num = i.convert("666");
System.out.println(num);
}
}
2.2 引用对象的实例方法
格式:对象::实例方法
package Lambda;
//接口
public interface Interface {
//传入字符串 大写输出
void upPrint(String s);
}
package Lambda;
//具体类
public class Print {
private String s;
void up(String s) {
System.out.println(s.toUpperCase());
}
}
package Lambda;
//测试类
public class Demo {
public static void main(String[] args) {
useInterface(s -> System.out.println(s.toUpperCase()));//HELLOWORLD
//引用对象实例方法
Print p = new Print();
useInterface(p::up);//HELLOWORLD
//Lambda表达式被对象的实例化方法替代的时候,他的形参(这里是s)全部传递给该方法(这里是up方法)作为参数
}
public static void useInterface(Interface i) {
i.upPrint("helloworld");
}
}
2.3 引用类的实例方法
格式:类名:成员方法
package Lambda;
//接口
public interface Interface {
//截取字符串
String sub(String s , int x, int y);
}
package Lambda;
//测试类
public class Demo {
public static void main(String[] args) {
//Lambda
useInterface((s, x, y) -> s.substring(x, y));
//引用类的实例方法
useInterface((String::substring));
//Lambda表达式被类的实例方法替代时候,
//第一个参数是调用者(也就是这里的s)
//后面的参数是该方法(也就是substring)的参数(x,y)
// (也就是说是s.substring(x,y))
}
public static void useInterface(Interface i) {
String s = i.sub("helloworld", 2, 5);
System.out.println(s);
}
}
2.4 引用构造器
就是引用构造方法
格式:类名::new
package Lambda;
//接口
public interface StudentBuilder {
//创建学生信息
Student builder(String name,int age);
}
package Lambda;
//学生构造类
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package Lambda;
//测试类
public class Demo {
public static void main(String[] args) {
//Lambda
/*useInterface((name,age)->{
Student s = new Student(name,age);
return s;
});*/
useInterface(((name, age) -> new Student(name, age)));//文天圣,22
//引用构造器
useInterface(Student::new);//文天圣,22
}
public static void useInterface(StudentBuilder sb) {
Student s = sb.builder("文天圣", 22);
System.out.println(s.getName() + ',' + s.getAge());
}
}
3. 弹幕:(感觉有点道理)
- Lambda表达式通过匿名内部类推导出来的,按照匿名内部类理解
- Lambda其实就是在重写接口里面的方法
- Lambda 不需要接口实例化的类了 简洁