本文共6150字,大约阅读8分钟
内部类及Lambda表达式
内部类
- 概念
在一个类的内部,定义了一个完整的类,称作内部类
//外部类
class Outer{
//内部类
class Inner{
}
}
- 内部类编译之后会生成独立的 .class 文件,.class文件命名方式为
外部类类名$内部类类名.class
- 内部类可以直接访问外部类的成员;
通常将内部类作为外部类的组件构成 - 内部类的分类
成员内部类、静态内部类、局部内部类、匿名内部类
成员内部类(类比于 实例变量)
- 位置
定义在类以内,方法以外 - 成员内部类对象的创建
成员内部类对象的创建,必须依赖于外部类的对象而创建
Outer o = new Outer(); //创建外部类的对象
Outer.Inner i = o.new Inner(); //创建成员内部类的对象
- 成员内部类可以直接访问外部类的属性和方法(私有的也可以访问)
- 外部类的当前对象
外部类类名.this
外部类类名.this.属性名 //访问外部类的属性
外部类类名.this.成员方法名(参数) ; //调用外部类的成员方法
- 成员内部类中不能定义静态成员(静态属性和静态方法)
成员内部类案例
public class TestInner {
public static void main(String[] args) {
Outer o = new Outer();
// 创建成员内部类的对象:必须依赖于 外部类的对象而创建
Outer.Inner i = o.new Inner();
System.out.println(i.n);
i.inner_method();
System.out.println(o.a);
}
}
// 外部类
class Outer{
int a = 3; // 实例变量
// 成员方法
public void outer_method() {
System.out.println("外部类的成员方法....");
}
// 成员内部类(类比于实例变量)
class Inner{
int n = 7;
int a = 6; // 成员内部类中属性
//static int m = 2;
public Inner() {}
public void inner_method() {
int a = 8;// 局部变量
System.out.println("内部类中成员方法....");
System.out.println("a="+a);
System.out.println("this.a="+this.a);
System.out.println("Outer.this.a="+Outer.this.a);
Outer.this.a = 10;
}
}
}
静态内部类(类比于 静态变量)
- 位置
定义在类以内,方法以外,被static修饰的内部类 - 静态内部类可以定义实例变量和静态变量(方法同)
- 创建静态内部类的对象
外部类类名.静态内部类的类名.引用名 = new 外部类类名.静态内部类类名(); - 访问静态内部类的静态成员
可以直接通过类名访问
外部类类名.静态内部类类名.静态属性 //访问静态内部类的静态属性
外部类类名.静态内部类类名.静态方法(实参) //访问静态内部类的静态方法
- 静态内部类只能直接访问外部类静态成员(静态属性和静态方法)
静态内部类中不能直接访问外部类的非静态成员
静态内部类案例
public class TestStaticInner {
public static void main(String[] args) {
System.out.println(MyClass.Inner.n);
MyClass.Inner.inner_static_method();
}
}
class MyClass {
int a = 2;// 实例变量
static int b = 5;// 静态变量
public void outer_method() {
System.out.println("外部类的成员方法!");
}
public static void outer_static_method() {
System.out.println("外部类的静态方法");
System.out.println("b=" + b);
}
// 静态内部类
static class Inner {
int m = 1;// 实例变量
static int n = 2;// 静态变量
public void inner_method() {
System.out.println("静态内部类类的成员方法!");
System.out.println("b=" + b);
}
public static void inner_static_method() {
System.out.println("静态内部类的静态方法");
}
}
}
打印结果↓↓↓
2
静态内部类的静态方法
局部内部类(类比于 局部变量)
- 位置
定义在函数、方法以内 - 创建局部内部类的对象,需要在定义它的方法内部完成对象的创建,同时创建对象应该在类定义以后位置(先定义类,再创建对象)
注意
局部内部类既可以定义在成员方法,也可以定义在静态方法 - 局部内部类可以直接访问外部类的成员(静态成员+非静态成员)
注意
局部内部类可以访问定义它的方法内部的局部变量,但是局部变量必须被final修饰,才能被局部内部类访问
JDK8.0版本及以上,如果JVM检测一个方法中局部变量被此方法内部的局部内部类方法访问,jvm默认在此局部变量前面加final,此语法被称为语法糖
局部内部类案例
public class TestLocalInner {
public static void main(String[] args) {
ClassA ca=new ClassA();
ca.outer_method();
}
}
class ClassA{
int n = 3;//实例变量
static int f=8;//静态变量
public void outer_method() {
System.out.println("外部类的成员方法");
int m=6;
System.out.println("m="+m);
//System.out.println("f="+f);
//局部内部类
class Inner {
int a=1;
public void inner_method() {
System.out.println("局部内部类的成员方法");
System.out.println("n="+n);
//System.out.println("f="+f);
System.out.println("m="+m);
}
}
//创建局部内部类的对象
Inner i=new Inner();
System.out.println(i.a);
i.inner_method();
}
}
打印结果↓↓↓
外部类的成员方法
m=6
1
局部内部类的成员方法
n=3
m=6
匿名内部类
- 匿名内部类
是一种特殊的局部内部类 - 特点
- 匿名内部类的定义必须继承一个父类或是嫌一个接口
- 基于一个匿名内部类只能创建该类的一个对象,并且匿名内部类的定义和对象的创建一起完成
- 语法
接口名 引用名 = new 接口名(){
// 接口中需要实现的方法 };
- 匿名内部类的优缺点
- 优点:减小代码量,让编程思路连贯
- 缺点:可读性低
匿名内部类案例1
interface IA{ //定义接口IA
void m1(); //接口中的方法
}
public class Test{
public static void main(String[] args){
IA ia = new IA(){
public void m1(){}
};
}
}
匿名内部类案例2
public class Test {
public static void main(String[] args) {
MyClass mc =new MyClass(){
public void method(){
System.out.println("子类覆盖后的方法。。。");
}
};
mc.method();
}
}
class MyClass{
public void method(){
System.out.println("父类中method方法/...");
}
}
匿名内部类案例3
public class TestAnonymousInner {
public static void main(String[] args) {
IB ib = new IB() {
public void m2() {
System.out.println("m2方法实现");
}
public void m3() {
System.out.println("m3方法实现");
}
};
ib.m2();
ib.m3();
test(new IB() {
public void m2() {
System.out.println("m2方法实现");
}
public void m3() {
System.out.println("m3方法实现");
}
});
}
public static void test(IB ib) {
ib.m2();
}
}
interface IB {
void m2();
void m3();
}
打印结果如下↓↓↓
m2方法实现
m3方法实现
m2方法实现
匿名内部类实战
1.匿名内部类实现接口:功能:判断两数之和是否大于100,是true 否false;
2.匿名内部类实现接口:功能:判断a-b是否大于0,是true 否false;
要求:调用接口方法,打印结果
public class TestAnonymousInner2 {
public static void main(String[] args) {
// 1.匿名内部类实现接口:功能:判断两数之和是否大于100,是true 否false
// 调用接口方法,打印结果
Toolable ta = new Toolable() {
public boolean isAccord(int a, int b) {
if (a + b > 100) {
return true;
} else {
return false;
}
}
};
System.out.println(ta.isAccord(5, 99));
// 2.匿名内部类实现接口:功能:判断a-b是否大于0,是true 否false
// 调用接口方法,打印结果
Toolable ta1 = new Toolable() {
public boolean isAccord(int a, int b) {
if (a - b > 0) {
return true;
} else {
return false;
}
}
};
System.out.println(ta.isAccord(5, 99));
}
}
interface Toolable {
boolean isAccord(int a, int b);
}
打印结果如下↓↓↓
true
false
Lambda表达式
- 功能
实现函数式接口并完成对象的创建,是匿名内部类简化形式 - 应用场景
当接口中只有一个抽象方法时(静态方法、默认方法不在其中) - 语法
接口名 引用 = (形参列表) ->{ //方法实现部分 };
- 语法解释
-> 是JDK8新引入的一个语法符号
-> 左侧:Lambda表达式参数,即接口方法中形参部分
-> 右侧:指Lambda表达式执行功能部分,即接口方法实现部分
- 语法解释
- 具体使用
- 无参数,无返回值
语法结构
接口名 引用 = () ->{ //方法实现部分 };
当{}中只有一行语句时,{}可略,但不建议 - 带有参数无返回值
语法结构
接口名 引用 = (数据类型 变量名,数据类型 变量名) -> { //方法实现 }
注意:Lambda表达式形参列表的数据类型可以省略,编译器自行推断 - 带有参数有返回值
语法结构
接口名 引用 = (形参列表) -> { return xxx; }
注意:如果{}中只有一条 return 语句,return语句和{}可 以省略(一 起)
- 无参数,无返回值
Lambda表达式案例
public class TestAnonymousInner3 {
public static void main(String[] args) {
// 无参无返回值方法的打印语法
IE ie = () -> System.out.println("aaa");
ie.ma();
// 有参无返回值方法的打印语法
IF If = (int a) -> {
System.out.println(a);
};
If.mf(3);
// 有参有返回值方法的打印方法
IG ig = (int a, int b) -> {
return a + b;
};
System.out.println(ig.mg(4, 5));
}
}
interface IE {
// 无参无返回值方法
void ma();
}
interface IF {
// 有参无返回值方法
void mf(int a);
}
interface IG {
// 有参有返回值方法
int mg(int a, int b);
}
打印结果如下↓↓↓
aaa
3
9扫描二维码关注公众号,回复: 10364724 查看本文章
Lambda表达式在实际问题中的使用
1.匿名内部类实现接口:功能:判断两数之和是否大于100,是true 否false;
2.匿名内部类实现接口:功能:判断a-b是否大于0,是true 否false;
要求:调用接口方法,打印结果
public class TestAnonymousInner2 {
public static void main(String[] args) {
// 1.匿名内部类实现接口:功能:判断两数之和是否大于100,是true 否false
// 调用接口方法,打印结果
// lambda简化
Toolable ta1 = (int a, int b) -> a + b > 100;
System.out.println(ta1.isAccord(2, 67));
// lambda 三目
Toolable ta2 = (int a, int b) -> a + b > 100 ? true : false;
System.out.println(ta2.isAccord(2, 67));
// lambda 条件判断
Toolable ta3 = (int a, int b) -> {
if (a + b > 100) {
return true;
} else
{
return false;
}
};
System.out.println(ta3.isAccord(2, 67));
System.out.println("+++++");
// 2.匿名内部类实现接口:功能:判断a-b是否大于0,是true 否false
// 调用接口方法,打印结果
// lambda简化
Toolable ta4 = (int a, int b) -> a - b > 0;
System.out.println(ta4.isAccord(87, 67));
// lambda 三目
Toolable ta5 = (int a, int b) -> a + b > 100 ? true : false;
System.out.println(ta5.isAccord(2, 67));
// lambda 条件判断
Toolable ta6 = (int a, int b) -> {
if (a + b > 100) {
return true;
} else
{
return false;
}
};
System.out.println(ta6.isAccord(2, 67));
}
}
interface Toolable {
boolean isAccord(int a, int b);
}
打印结果如下↓↓↓
false
false
false
+++++
true
false
false
整理不易,喜欢请点个赞!
编者微信:1014961803,添加时请备注"CSDN"