【方式一】

【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();