Lambda表达式与匿名内部类

匿名内部类

匿名内部类适合创建那种只需要一次使用的类,匿名内部类的语法有点奇怪,创建匿名内部类时会立即创建一个该的实例,这个定义立刻消失,匿名内部类不能重复使用(一次性的)

  • 定义匿名内部类的格式如下:
new 实现接口()  | 父类构造器(实参列表)
 {
  	//匿名内部类的类体部分
 }
  • 匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承一个父类,或实现一个接口
  • 匿名内部类有如下规则
  1. 匿名内部类不能是抽象类,因为系统在创建匿名内部类时,会立即创建匿名内部类的对象。因此不允许将匿名内部类定义成抽象类。

  2. 匿名内部类不能定义构造器。由于匿名内部类没有类名,所以无法定义构造器,但匿名内部类可以定义初始化块,可以通过实例初始化块来完成构造器需要完成的事情。

  3. 通过实现接口来创建匿名内部类时,匿名内部类也不能显示创建构造器,因此匿名内部类只有一个隐式的无参构造器,故 new 接口名后的括号里不能传入参数值。(无参构造)

  4. 通过继承父类来创建匿名内部类时,匿名内部类将拥有和父类相似的构造器,此处的相似指拥有相同的形参列表。

  5. 创建匿名内部类时,必须实现接口或抽象父类里的所有抽象方法。

下面对应解释说明:

  1. 因为抽象类有构造器但不能直接实例化(因为有抽象方法);上列已经得知创建内部类时会立即创建内部类对象。抽象类是不能实例的,只能作为父类被继承,由子类实现抽象类里的抽象方法。

  2. 匿名内部类不能定义构造器,这个好理解,因为构造器就是一个没有返回值,方法名和类一样的构造方法而已,类都是匿名的你怎么定义构造器呢?

  3. 实现接口创建匿名内部类时,匿名内部类不能显示创建构造器;我们先回顾下接口,接口里不能包含构造器和初始化块因为 接口里成员变量只能是静态常量,接口里的方法只能是抽象方法、类方法、默认方法

  4. 继承父类来创建匿名内部类,匿名内部类将拥有和父类相似的构造器,这个没什么解释,知道就可以它的规则就是这样。

  5. 匿名内部类也是类,也需要遵守继承类/抽象类 或 实现接口的规则。

  • 最后我们来分析一下这个 定义匿名内部类的格式:
new 实现接口()  | 父类构造器(实参列表)
 {
  	//匿名内部类的类体部分
 }
  1. 通过实现接口来创建匿名内部类
    new 实现接口 (){ } 会得到一个实现此接口的类的实例/对象
    例如 :new A() { } 会得到一个实现了A接口的类的实例
    (A此例中代表接口)

  2. 通过继承父类来创建匿名内部类
    new 父类构造器(实参列表){ } 会得到一个继承了该类的子类实例 / 对象
    例如 :new B() { } 会得到一个继承了B类的子类实例
    (B此例中代表父类)

Lambda表达式

这是Java 8 的重要更新,Lambda表达式支持将代码块作为方法参数,Lambda 表达式允许使用更简洁的代码来创建只有一个抽象方法的接口(这种接口被称为函数式接口)的实例。

  • Lambda表达式可以简化匿名内部类对象,不需要new Xxx(){}这种繁琐的代码,不需要指出重写的方法名字,也不需要给出重写的方法的返回值类型-----只要给出重写的方法括号以及括号里的形参列表即可。

  • 使用Lambda表达式代替匿名内部类创建对象时,Lambda表达式的代码块会代替实现抽象方法的方法体,Lambda表达式就相当一个匿名方法。

  • Lambda由3部分组成

  1. 形参列表。允许省略形参类型,如果形参列表中只有一个参数,甚至连形参列表的圆括号也可以省略。
  2. 箭头(->)
  3. 代码块。如果代码块只包含一条语句,Lambda表达式允许省略代码块的花括号,那么这条语句就不要用花括号表示语句结束。Lambda代码块只有一条return语句,甚至可以省略return关键字,Lambda表达式需要返回值,而他的代码块中仅有一条省略了return的语句,Lambda表达式会自动返回这条语句的值。
说了这么多,先来个实例吧!
interface It{	//函数式接口(只有一个抽象方法)
   void hi(String s);	//此接口只有个抽象方法hi(String s)
}
  • 使用Lambda表达式创建一个 It 对象(实际类型是lt接口实现类的实例,自动向上转型了)
	It  t = s->System.out.println(s);
		 t.hi("大家好!");//输出 大家好!
  • 上列利用了lambda表达式实现了如上匿名内部类一样的效果,
  • 最后说明下:,同样的 Lambda 表达式的目标类型完全可能是变化的 -----唯一的要求是,Lambda 表达式实现的匿名方法与目标类型 (函数式接口)中唯一的抽象方法有相同的形参列表

最后介绍下方法引用与构造器引用

  • 如果 Lambda 表达式的代码块只有一条代码,程序就可以省略 Lambda 表达式中代码的花括号{}.不仅如此,如果 Lambda 表达式的代码块只有一条代码,还可以在代码块中使用方法引用和构造器引用。

  • 方法引用和构造器引用可以让 Lambda 表达式的代码更简洁。方法引用和构造器引用都需要使用 两个英文冒号。Lambda 表达式支持如下表几种引用方式。

种类示例对应的 Lambda表达式
引用类方法类名::类方法(a,b…)->类名.类方法(a,b…)
引用特定对象的实例方法特定对象::实例方法(a,b…)->特定对象.实例方法(a,b…)
引用某类对象的实例方法类名::实例方法(a,b…)->a.实例方法(b…)
引用构造器类名::new(a,b…)->类名(a,b…)
  • 对应的说明参考下列:
  1. 函数式接口中被实现的全部参数传给该类方法作为参数
  2. 函数式接口中被实现的全部参数传给该类方法作为参数
  3. 函数式接口中被实现方法的第一个参数作为调用者,后面的参数全部传给该方法作为参数
  4. 函数式接口中被实现的全部参数传给该类方法作为参数
  • 赶着写作业了,就借助上面例子来个示例:
interface It{	//函数式接口(只有一个抽象方法)
   void hi(String s);	//此接口只有个抽象方法hi(String s)
}
  • 使用Lambda表达式创建一个 It 对象(实际类型是lt接口实现类的实例,自动向上转型了)
	It  t = s->System.out.println(s);
		 t.hi("大家好!");//输出 大家好!
  • 引用特定对象的实例方法
	It  t = System.out::println;
		 t.hi("大家好!");//输出 大家好!

先溜了,如有哪里需要补充请留言,多实践!

  • 5
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值