前言:本部分内容关联性很强,尤其是了解由匿名内部类 =>lamada表达式 =>方法引用的递进关系,后续的内容中,方法引用可能用的不多,见到认识即可,但是匿名内部类和lamada表达式是非常通用的表达方式。
1. 内部类
当一个类的内部,包含了一个完整的事物,且这个事物没有必要单独设计时,就可以把这个事物设计成内部类。
1.1 成员内部类
//书写格式
public class Outer {
public class Inner {
}// 成员内部类
}//外部类
//成员内部类 实例化语法
//外部类名.内部类名 对象名 = new 外部类(...).new 内部类(...);
Outer.Inner in = new Outer().new Inner();
特点:
- 可以直接访问外部类的实例成员、静态成员(也包括其私有成员)
- 成员内部类的成员方法对于局部变量、成员内部类的成员变量、外部类的成员变量,可以通过XXX、内部类类名.this.XXX、外部类.this.XXX。
1.2 静态内部类
静态内部类,还是个普通类,其实就是外部类的静态成员,只不过访问它的时候,无需实例化外部类。
//书写格式
public class Outer{
public static class Inner{
} // 静态内部类
}//外部类
//实例化格式
//外部类名.内部类名 对象名 = new 外部类.内部类(…); //此时外部没有被实例化
Outer.Inner in = new Outer.Inner();
特点:
- 可以直接访问外部类的静态成员,不可以直接访问外部类的实例成员,其实很好理解,因为外部没有被实例化,只是借用了外部的名字。
1.3 局部内部类
定义:局部内部类是定义在在方法中、代码块中、构造器等执行体中。
其实概念跟之前成员方法的局部变量很相似,就是只能在这个方法中使用,出了方法就会消失。
1.4 匿名内部类(超重点)
特点:
- 是一种特殊的局部内部类
- 匿名内部类本质就是一个子类,并会立即创建出一个子类对象
- 父类可以是普通类、抽象类、接口。
//语法格式
new 类或接口(参数值…) {
类体(一般是方法重写);
};
//实例
Animal animal1 = new Animal(){
//new出来的父类Animal 直接加{}就是在写子类内容
@Override
public void cry() {
}
};
animal1.cry();//执行子类的重写方法
此过程中,执行了三个过程,立即 创建了一个子类,且进行实例化,且重写父类中的方法,此时我们就可以用Animal animal来接收这个匿名子类。
功能:用来快速创建子类。
有以下几种情况,不推荐使用匿名内部类:
- 匿名内部类的重写方法过程太复杂。
- 接口中有太多需要重写的抽象方法。
- 接口创建的匿名内部类需要有继承的父类。
2. Lamada表达式(重点)
Lambda函数替代某些****匿名内部类对象,从而让程序代码更简洁,可读性更好。
特点:
- lamada表达式只能代替函数式接口的匿名内部类
- 函数式接口:要求接口只有一个抽象方法。函数式接口有**@FunctionalInterface**注解
//函数式接口
@FunctionalInterface//标志,可以不写,写了会帮我们自己检测
public interface Swimmable {
public void swim();
}
// Lamada语法格式
(被重写方法的形参列表) -> {
被重写方法的方法体代码。
}
//案例:
public class SwimmingTest {
public static void main(String[] args) {
Swimmable s1 = new Swimmable() {
@Override
public void swim() {
System.out.println("老师游泳");
}
};//不写简写的匿名内部类
Swimmable s2 = () -> {
System.out.println("lamada表达式");
};//使用lamada简写的匿名内部类
}//main
lamada表达式进阶:
核心主旨:可推导,可省略
- 参数类型全部可以省略不写
- 如果只有一个参数,参数类型省略的同时, () 也可以省略,但多个参数不能省略“()”
- 如果Lambda表达式中只有一行代码,大括号可以不写,同时要省略分号“;” 如果这行代码是return语句,也必须去掉return
30s方法快捷键:鼠标放在函数式接口的名字上,Alt+回车,可选择替换为lamada表达式
//摘抄习题:
// 定义测试类(答案为A)
public class AddableDemo
public static void main(string[] args){// 使用Lambda补全代码,完成两个数求和的功能!
useAddable(
public static void useAddable(Addable a){int sum= a.add(10,20);
System.out.println(sum);
A、(x,y)-> x+y //全部省略
B、(int x,int y)-> return x+y;//对于lamada表达式,其return语句需要放在{}中
C、(intx,inty)->{x+ y; }//无return语句
D、(x,inty)->{return x+ y;}
3. 方法引用
特定情况下,对lamada方法的进一步简化。
3.1 静态方法引用
了解:看案例即可
//函数式接口AddMethods中
package com.ithiema.practice;
@FunctionalInterface
public interface AddMethods {
int add(int a, int b);
}
//Test类文件中
package com.ithiema.practice;
public class AddTest {
public static void main(String[] args) {
AddMethods add1 = (a, b) -> a + b; //lamada表达式(旧)
AddMethods add2 = AddTest::sum; //使用静态方法代替lamada表达式
calculate(AddTest::sum);
}//main
public static void calculate(AddMethods a) {
a.add(10, 20);
}需要数据类型为接口的函数
public static int sum(int number1, int number2) {
return number1 + number1;
}//AddTest的静态方法
}
3.2 实例方法的引用
与静态方法非常相似,无非一个使用静态方法简化,一个通过实例方法简化
package com.ithiema.practice;
public class AddTest {
public static void main(String[] args) {
AddMethods add1 = (a, b) -> a + b; //lamada表达式(旧)
AddTest t = new AddTest();//实例化
AddMethods add2 =t::sum1 ;//使用静态方法代替lamada表达式
calculate(t::sum1);//调用实例方法
}
public static void calculate(AddMethods a) {
System.out.println(a.add(10, 20));
}//静态方法
public int sum1(int number1, int number2) {
return number1 + number1;
}//AddTest的实例方法
3.3 构造器引用
语法:类名::new
package com.ithiema.practice;
@FunctionalInterface
public interface Studentable {
public Student outStudent();
}//抽象方法的outStudent()返回值类型Student
//Student类
package com.ithiema.practice;
public class Student {
public Student() {
}//无参构造器
}
//测试类
package com.ithiema.practice;
public class StudnetTest {
public static void main(String[] args) {
Studentable stu1 = Student::new;
//此时就用Student的构造器构造一个Student类返回给抽象方法
}
}
3.4 特定类的方法引用(了解)
语法:特定类的名称::方法
//函数式接口
package com.ithiema.inferance;
@FunctionalInterface
public interface Studentable {
public void put(Student stu1, int age, String name);
}
//Student类
package com.ithiema.inferance;
public class Student {
String name;
int age;
public void sayhai(int age,String name){
System.out.println("你好");
}
}
//StudentTest测试
package com.ithiema.inferance;
public class StudentTest {
public static void main(String[] args) {
Student student = new Student();
Studentable s = Student::sayhai;
s.put(student,19,"张三");
}//main
}
总结:这种特定类方法要求的条件过于苛刻,更是用的不多,碰到了也不太可能会专门简化成这样,lamada格式以及非常简化了。
标签:java,内部,int,void,lamada,引用,Student,public From: https://blog.csdn.net/m0_56827189/article/details/145017509