定义: 匿名内部类是没有名称的内部类
说明: 在调用包含有接口类型参数的方法时,通常为了简化代码,可以直接通过匿名内部类的形式传入一个接口类型参数,在匿名内部类中直接完成方法的实现。
/*
*匿名内部类的前提
*必须是类或者接口
*
*格式:
*
*new 类名/接口名(){
*重写抽象方法
*}
*/
public class Demo01 {
public static void main(String[] args) {
//整体等效于:是Animal父类的子类对象
//new Animal(){
// @Ovrride
// public void eat() {
// System.out.println("我吃饭");
// }
//};
//方法一
new Animal(){
@Ovrride
public void eat() {
System.out.println("我吃饭");
}
}.eat();
//方法二
//通过匿名内部类访问局部变量.在JDK版本之前,必须加final关键字
String name = "路西法";
Animal a = new Animal(){
@Ovrride
public void eat() {
System.out.println(name+"在吃饭");
}
};
a.eat();
}
}
public abstract class Animal {
public abstract void eat();
}
public class Dog extends Animal{
@Ovrride
public void eat() {
System.out.println("狗吃肉");
}
}
public class Demo02 {
public static void main(String[] args) {
function(
new Inner() {
@Ovrride
public void method() {
Sysytem.out.println("我重写后的menthod方法");
}
}.method();
);
}
public static void function(Inter i) {
i.method();
}
}
public interface Inter {
public abstract void method();
}
Lambda表达式介绍
Java8的一个大亮点是引入Lambda表达式,使用它设计的代码会更加简洁。通过Lambda表达式,可以替代我们以前经常写的匿名内部类来实现接口。Lambda表达式本质是一个匿名函数
Lambda表达式语法
(int a,int b) -> (return a+b);
本质是一个函数;
一般的函数类似如下:
int add(int a,int b) {
return a+b;
}
有返回值,方法名,参数列表,方法体
Lambda表达式函数的话,只有参数列表和方法体
(参数列表) -> {方法体}
说明:
(): 用来描述参数列表
{}: 用来描述方法体
->: Lambda运算符,可以叫做箭头符号,或者goes to
案例;接口方法参数,无参,单个参数,两个参数,有返回值,没有返回值,这六种情况都罗列下:
public class Program {
public static void main(String[] args) {
If1 if1 = ()->{
System.out.println("无参数无返回值");
};
if1.test();
If2 if2 = (int a)->{
System.out.println("单个参数无返回值 a="+a);
if2.test(3);
If3 if3 = (int a,int b)->{
System.out.println("两个参数无返回值 a+b"+(a+b));
};
if3.test(1,5);
If4 if4 = ()->{
return 4;
};
System.out.println("无参数有返回值"+if4.test();
If5 if5 = (int a)->{
return a;
};
System.out.println("单个参数有返回值"+if5.test(5));
If6 if6 = (int a,int b)->{
return a-b;
};
System.out.println("多个参数有返回值"+if6.test(7,1));
}
interface If1{
/**
*无参数无返回值
*/
void test();
}
interface If2{
/**
*单个参数无返回值
*/
void test(int a);
}
interface If3{
/**
*两个参数无返回值
*/
void test(int a,int b);
}
interface If4{
/**
*无参数有返回值
*/
int test();
}
interface If5{
/**
*单个参数有返回值
*/
int test(int a);
}
interface If6{
/**
*多个参数有返回值
*/
int test(int a,int b);
}
}
Lambda表达式精简语法
1.参数类型可以省略
2.假如只有一个参数,()括号可以省略
3.如果方法体只有一条语句,{}大括号可以省略
4.如果方法体中唯一的语句是return返回语句,那省略大括号的同时return也要省略
public class Program2 {
public static void main(String[] args) {
If1 if1 = ()->System.out.println("无参数无返回值");
if1.test();
If2 if2 = a->System.out.println("单个参数无返回值 a="+a);
if2.test(3);
If3 if3 = (a,b)->System.out.println("两个参数无返回值 a+b"+(a+b));
if3.test(1,5);
If4 if4 = ()-> 4;
System.out.println("无参数有返回值"+if4.test();
If5 if5 = a->a;
System.out.println("单个参数有返回值"+if5.test(5));
If6 if6 = (a,b)->a-b;
System.out.println("多个参数有返回值"+if6.test(7,1));
}
interface If1{
/**
*无参数无返回值
*/
void test();
}
interface If2{
/**
*单个参数无返回值
*/
void test(int a);
}
interface If3{
/**
*两个参数无返回值
*/
void test(int a,int b);
}
interface If4{
/**
*无参数有返回值
*/
int test();
}
interface If5{
/**
*单个参数有返回值
*/
int test(int a);
}
interface If6{
/**
*多个参数有返回值
*/
int test(int a,int b);
}
}
public class Program3 {
public static void main(String[] args) {
//If5 if5 = a->a-2;
//System.out.println(if5.test(3));
//If5 if52 = a->a-2;
//System.out.println(if5.test(5));
Program3 program3 = new Program3();
If5 if5 = program3::testA;
System.out.println(if5.test(3));
If5 if52 = program3::testA;
System.out.println(if52.test(5));
If5 if53 = Program3::testB;
If5 if54 = Program3::testB;
System.out.println(if53.test(3));
System.out.println(if54.test(3));
}
public int testA(int a) {
return a-2;
}
public static int testB(int a) {
return a-2;
}
interface If5{
/**
*单个参数有返回值
*/
int test(int a);
}
}
构造方法引用
如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现,那么就可以使用构造方法引用;
语法:类名::new
实例:
先定义一个Dog实体,实现无参和有参构造方法;
public class Dog {
private String name;
private int age;
public Dog() {
System.out.println("无参构造方法");
}
public Dog(String name,int age) {
System.out.println("有参构造方法");
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 getAge(int age) {
this.age = age;
}
@Ovrride
public String toString() {
return "Dog(" +
"name+'" + name + '\' +
", age=" + age +
")";
}
}
public class Program4 {
public static void main(String[] args) {
/*DogService dogService=()->{
return new Dog();
};
System.out.println(dogService.getGog());*/
/*DogService dogService=()->new Dog();
System.out.println(dogService.getGog());*/
DogService dogService=Dog::new;
System.out.println(dogService.getGog());
DogService dogService2=Dog::new;
System.out.println(dogService2.getDog("向玉明",24))
}
interface DogService{
Dog getDog();
}
interface DogService2{
Dog getDog(String name,int age);
}
}
@FunctionallInterface注解
这个注解是函数式接口注解,所谓的函数式接口,首先的一个接口,然后这个接口里面只能有一个抽象方法
这种类型的接口也成为SAM接口,即Single Abstract Method interfaces
特点
//正确的函数式接口
@FunctionalInterface
public interface TestInterface {
//抽象方法
public void sub();
//java.lang.Object中的public方法
public boolean equals(Object var1);
//默认方法
public default void defaultMethod(){
}
//静态方法
public static void staticMethod(){
}
}
//错误的函数式接口(有多个抽象方法)
@FunctionalInterface
public interface TetInterface2 {
void add();
void sub();
}