内部类,Lambda表达式
内部类
内部类-成员内部类
什么是内部类
在一个类中定义一个类
举例:在一个类A的内部定义一个类B,类B就被称为内部类
class A{
class B{
...
}
}
如何定义以个内部类
- 格式&举例
class 外部类名{
修饰符 class 内部类名{
}
}
内部类的分类
- 在类的成员位置:成员内部类
- 在类方法内位置:局部内部类
外部如何使用普通成员内部类
格式: 外部类名.内部类名 对象名 = new 外部对象().new 内部对象();
范例:Outer.Inner oi = new Outer().new Inter();
public class OuterClass_And_InnerClass {
public static void main(String[] args) {
// 调用内部类的方法
// 1.先创建对象
Outer.Inner inner = new Outer().new Inner();
// 2.调用内部类的方法
inner.show();
}
}
// 外部类
class Outer{
// 内部类
class Inner{
// 内部类的show方法
public void show(){
System.out.println("这是一个内部类");
}
}
}
成员内部类的访问非静态成员时有什么特点
1.内部类可以直接访问外部类的成员,包括私有
2.外部类要访问内部类的成员,必须要创建对象
成员内部类的分类
普通成员内部类
私有成员内部类
静态成员内部类
私有成员内部类-静态成员内部类
私有成员内部类的访问特点?
只能在自己所在的外部类中创建对象访问
如何创建静态成员内部类对象?
外部类名.内部类名 对象名 = new 外部类名.内部类名();
如何访问静态成员内部类中的静态方法
外部类名.内部类名.方法名();
/*
1. 内部类可以直接访问外部类的成员,包括私有
2. 外部类要访问内部类的成员,必须创建对象
*/
// 外部类
public class InnerClass{
// 调用内部类的方法
public static void main(String[] args) {
// 1.. 内部类可以直接访问外部类的成员,包括私有
OuterInner.Inner inner = new OuterInner().new Inner();
System.out.println(inner.show());
// // 2.. 外部类要访问内部类的成员,必须创建对象
OuterInner out = new OuterInner();
out.show();
}
}
// 外部类
class OuterInner {
// 内部类
private int num = 10;
class Inner{
// 内部类的show方法
public String show(){
return num+"这是一个内部类";// 1.内部类可以直接访问外部类的成员,包括私有的
}
}
public void show(){
Inner inner1 = new Inner(); // 2. 外部类要访问内部类的成员,必须创建对象
System.out.println("使用了内部类的方法"+inner1.show());
}
}
局部内部类
什么是局部内部类
在方法内部定义的类
如何使用局部内部类
局部内部类外界无法使用,需要在方法内部创建对象并使用
局部内部类有什么特点
局部内部类是在方法中定义的类
该类可以直接访问外部类的成员,也可以访问方法内的局部变量
匿名内部类
什么是匿名内部类
没有显式的名字的内部类
使用匿名内部类的前提
存在一个类或者接口,这里的类可以是具体类也可以是抽象类
如何使用匿名内部类
new 类名(){重写方法}
new 接口名(){实现方法}
示例
package myclass;
public class ClassDemo {
public static void main(String[] args) {
// 将实现和方法重写,创建对象放在了一步进行
Out o = new Out() {
@Override
void show() {
System.out.println("重写show方法1");
}
};
// 调用方法
o.show();
// 将继承或实现,方法重写,创建对象,调用方法,放在了一步进行
new Out(){
void show(){
System.out.println("重写show方法");
}
}.show();
}
}
//定义一个抽象类,只有一个show方法
abstract class Out{
abstract void show();
}
匿名内部类的本质是什么
是一个继承了该类,或者实现了该接口的子类匿名对象
匿名内部类的使用场景
当发现某个方法需要接口或者抽象类的子类对象,我们就可以传递一个匿名内部类过去,来简化传统对象
Lambda表达式
什么是函数式编程的思想
函数式思想尽量忽略面向对象的复杂语法: “强调做什么,而不是以什么形式去做”
面向对象思想和函数式编程思想对比
面向对象思想强调"必须通过对象的形式来做事情"
函数式思想则尽量忽略面向对象的复杂语法:“强调做什么,而不是以什么形式去做”
Lambda表达式的前提条件
有一个接口,接口中只能由一个抽象方法
如何使用Lambda表达式
格式
(形式参数)->{代码块}
组成Lambda表达式的三要素
形式参数:如果由多个参数,参数之间用逗号隔开;如果没有参数,留空即可
->:由英文中画线和大于符号组成,固定写法.代表指向动作
代码块:是我们具体要做的事情,也就是以前我们写的方法体内容
无参无返回值
()->System.out.println("我是Lambda中的show方法")
有参无返回值
msg->System.out.println("我是Lambda表达式"+msg)
无参数有返回值
()->{
Random ran = new Random();
int num = ran.nextInt(10)+1;
return num;
// 注意:如果lambda所操作的接口中的方法,有返回值,一定要通过return语句将结果返回
}
带参数有返回值
// 示例一
(int a,int b)->{
return a+b;
}
// 示例二
(a,b)->{
return a+b;
}
Lambda表达式的省略规则
- 参数类型可以省略.但是有多个参数的情况下,不能只省略一个
- 如果参数有且仅有一个,小括号可以省略
- 如果代码块的语句只有一条,可以省略大括号和分号,和return关键字
示例
package myclass;
public class LambdaDemo {
public static void main(String[] args) {
// Lambda表达式的使用前提
// 首先是接口,并且接口中仅有一个抽象方法
getShow(()->{
System.out.println("show方法");
});
}
public static void getShow(Out2 out2){
out2.show();
}
}
//定义一个接口类,只有一个show方法
interface Out2 {
void show();
}
Lambda表达式和匿名内部类的区别
所需对象不同
匿名内部类:可以是接口,也可以是抽象类,还可以是具体类
Lambda表达式:只能是接口
使用限制不同
如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类
如果接口中多余一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式
实现原理不同
匿名内部类:编译之后产生一个单独的.class字节码文件
Lambda表达式:编译之后,没有一个单独的.class字节码文件.对应的字节码会在运行时候动态生成