【方式一】
【demo】
假设我们有这么个接口
public interface Frozen1 {
String frozen1();
}
这里是接口的实现
public class Frozen1impl implements Frozen1 {
@Override
public String frozen1() {
String str = "这里是frozen1的实现方法";
System.out.println(str);
return str;
}
public String frozenself(){
String str = "这里是frozen1的特有的方法";
System.out.println(str);
return str;
}
}
现在我只想,调用frozen1() 这个方法:我们可以通过下面的两个方式
//方式1接口类型的引用变量A 去接收对象地址
Frozen1 frozen1 = new Frozen1impl();
frozen1.frozen1();
//方式2类类型的引用变量A 去接收对象地址
Frozen1impl frozen1impl = new Frozen1impl();
frozen1impl.frozen1();
frozen1impl.frozenself();
实例化对象调用方法,方式1实例化的对象只能调用接口中有的方法,而不能调用类中特有的方法。
这里引入多态的概念 假设Frozen1的实现不止一个
public class Frozen11impl implements Frozen1 {
@Override
public String frozen1() {
String str = "一个借口多个实现,来体现一下:多态";
System.out.println(str);
return str;
}
}
方法1的实现:使用接口编程的好处是统一规范化。你会发现无论多少个实现类,无论这些实现类有什么不同,使用接口 对象名 = new 类名; 方式实例化对象都可以调用接口中定义的方法。
//方式1接口类型的引用变量A 去接收对象地址
Frozen1 frozen1 = new Frozen1impl();
frozen1.frozen1();
frozen1 = new Frozen11impl();
frozen1.frozen1();
【ps:接口可以多继承】
【方式二】
Java调用第三方接口,这方面参考:《浅析HttpClient数据推送》
【方式三】
使用Java 8 Lambda 表达式 Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。 使用 Lambda 表达式可以使代码变的更加简洁紧凑。
【语法】
(parameters) -> expression或(parameters) ->{ statements; }
【说明】 lambda表达式允许你通过表达式来代替功能接口,允许使用更简洁的代码来创建只有一个抽象方法的接口的实例。Lambda 表达式的目标类型必须是"函数式接口( functional interface ) 。函数式接口代表只包含一个抽象方法的接口 。函数式接 口可以包含多个默认方法、类方法,但只能声明一个抽象方法。
【特性】 1、可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。 2、可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。 3、可选的大括号:如果主体包含了一个语句,就不需要使用大括号。 4、可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。
【demo】 在类中定义接口
public class Frozen0412 {
public static void main(String[] args) {
Frozen0412 tester = new Frozen0412();
Redant frozen1 = (String a, String b) -> "声明类型" + a + b;
Redant frozen2 = (a, b) -> "省略类型" + a + b;
Redant frozen3 = (a, b) -> { return "返回加个return+大括号"+a + b; };
System.out.println(tester.operate("redant","frozen", frozen1));
System.out.println(tester.operate("redant","frozen", frozen2));
System.out.println(tester.operate("redant","frozen", frozen3));
}
interface Redant {
String deal(String a, String b);
}
private String operate(String a, String b, Redant redant){
return redant.deal(a, b);
}
}
//同理,结合方法一的内容,我们还可以这么写
Frozen1 frozen11 = () -> "dededewdewdewdedewded";
System.out.println(frozen11.frozen1());
在我理解:“接口 对象名 = 参数 -> 接口实现”
【拓展】
1、@FunctionalInterface
修饰函数式接口的,要求接口中的抽象方法只有一个。 这个注解往往会和 lambda 表达式一起出现。
@FunctionalInterface
public interface Frozen2 {
String frozen2(String a, String b);
}
2、lambda 表达式引用方法 有时候我们不是必须要自己重写某个匿名内部类的方法,我们可以可以利用 lambda表达式的接口快速指向一个已经被实现的方法。
【语法】
方法归属者::方法名 静态方法的归属者为类名,普通方法归属者为对象 【demo】
public class Abcc {
public static String frozen() {
String str = "lambda表达式, 引用了已经实现的 frozen方法";
System.out.println(str);
return str;
}
}
//lambda 引用了已经实现的 doubleNum 方法
Frozen3 frozen = Abcc::frozen;
//接口 对象名 = 类名::同参数的接口实现
frozen.frozen3();
3、构造方法的引用 一般我们需要声明接口,该接口作为对象的生成器,通过 类名::new 的方式来实例化对象,然后调用方法返回对象。
public class People {
private String name;
private int age;
}
interface PeopleCreate {
People getItem();
}
PeopleCreate peopleCreate = People::new;
People item = peopleCreate.getItem();
4、lambda 表达式创建线程 线程:我们都是通过创建 Thread 对象,然后通过匿名内部类重写 run() 方法,一提到匿名内部类我们就应该想到可以使用 lambda 表达式来简化线程的创建过程。
Thread t = new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println("Frozen测试" + ":" + i);
}
});
t.start();