概述
内部类与Lambda表达式
内部类
概述
再一个类(A)的内部,又写了其他的类(B),此时B类就是A类的内部类;
分类
按照内部类再外部类的位置,可以分为局部内部类和成员内部类
- 局部内部类:写在了外部类的方法中;
- 成员内部类:写在了外部类的成员变量位置;
真正使用的都是匿名内部类;
内部类调用
public class Test {
public static void main(String[] args) {
A.C c = new B().new C();
}
}
class A {
class C {
}
}
匿名内部类(重点)
匿名内部类实际上是局部内部类的简化形式;
我们写了一个不带名字的局部内部类就是匿名内部类;(集类的编写,对象的创建与一体)
概述
编写没有名字的类;
语法要求:这样的类必须又一个父类或接口,并且写完这个类以后,需要立刻创建对象;
语法格式
new 父类或接口(){
重写父类或接口方法;
};
匿名对象
创建了一个没有名字的对象就是匿名对象
案例分析与实现
创建了一个CatInter的接口,再实现该接口打印猫吃鱼
按照以往操作,需要先创建接口CatInter,再创建该接口的实现类CatImpl,重写接口中的eat方法,打印"猫吃鱼",最后在主方法中创建CatImpl对象,调用其中的eat方法完成打印
而学习过匿名内部类后,就可以在主方法中直接创建CatInter的内部类,重写中的方法,在调用该方法就完成了
public class Test1_InnerClass {
public static void main(String[] args) {
/*
匿名内部类
父类是CatInter,但这个类本身没有名字
*/
new CatInter() {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}.eat();
}
}
interface CatInter {
void eat();
}
但思考,如果在接口中又添加了一个drink的方法,我们是不可以做}.eat.drink
这样的操作的,如果是这样的情况,我们需要将该对象保存到一个变量中去,再分别调用其中的eat方法和drink方法就可以了
public class Test2_InnerClass {
public static void main(String[] args) {
/*
匿名内部类
父类是CatInter,但这个类本身没有名字
这个对象被保存到变量cat中
*/
CatInter cat = new CatInter() {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
@Override
public void drink() {
System.out.println("猫喝水");
}
};
cat.eat();
cat.drink();
}
}
interface CatInter {
void eat();
void drink();
}
Lambda表达式
概述
lambda是java在jdk8开始新增的一种语法,这种语法允许我们在调用带有接口类型的形参的方法时,使用lambda作为方法的实参使用(lambda是需要根据调用的场景自动进行推导的)
使用前提
方法的形参必须必须是接口类型,且接口中有且只有一个抽象方法
lambda的基本语法
(参数列表) -> {方法体;return 返回值;}
lambda必须作为方法的实参使用
省略规则
- 参数类型可以省略,但有多个参数的情况下,不能只省略一个
- 如果参数有且仅有一个,那么小括号可以省略
- 如果代码块的语句只有一条,可以省略大括号、分号和return
lambda与匿名内部类的区别
所需类型不同
- 匿名内部类:可以是接口、抽象类或者是具体类
- Lambda:只能是接口
使用限制不同
- 如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类
- 如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式
实现原理不同
- 匿名内部类:编译之后产生一个单独的.class字节码文件
- Lambda:编译之后没有一个单独的.class字节码文件;对应的字节码会在运行的时候动态生成
案例分析与实现
创建Swim接口,其中有个一个swimming方法,需要传入一个字符串类型的name;建立一个goSwimming的方法,需要传入一个接口类型的swim,调用里面的swim方法,输入名字,返回一个swimming字符串,并打印xxx去游泳。
该案例我们可以使用匿名内部类来写,现在我们既然学习了Lambda表达式,我们就可以更简洁的来写
我们看形参为接口类型,接口中有且仅有一个抽象方法,我们可以使用Lambda表达式
lambda的基本语法看接口中抽象方法中的需要一个String类型的name,所以小括号中填写(String name)
,代码需要实现name去游泳并返回该字符串,所以用字符串拼接的方法拼接字符,然后将拼接好的字符串返回return name + "去游泳";
,得到lambda表达式(String name) ->{return name + "去游泳";}
,最后根据省略规则,参数类型可以不写,参数只有一个,小括号可以不写,代码块中只有一条代码,大括号、return、分号也可以不写,最终的lambda表达式为name ->return name + "去游泳"
public class TestSwimming {
public static void main(String[] args) {
goSwimming(name -> {
return name + "去游泳";
});
}
public static void goSwimming(Swim swim) {
String swimming = swim.swimming("张三");
System.out.println(swimming);
}
}
interface Swim {
String swimming(String name);
}
lambda传递过程
- 调用goSwimming方法,将lambda表达式作为实参传递给swim
- 调用swim中的swimming方法,将输入的姓名"张三"传递给lambda表达式的name
- 执行代码块中的代码
最后
以上就是陶醉小土豆为你收集整理的JavaSE进阶 内部类与Lambda表达式内部类与Lambda表达式的全部内容,希望文章能够帮你解决JavaSE进阶 内部类与Lambda表达式内部类与Lambda表达式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复