目录
内部类
将一个类嵌套到另一个类内部
将内部类看作类中的一个普通属性来看待
为何要将一个类放入另一个类内部?
封装
保护性&易用性
封装不只有private对属性的封装
分类
成员内部类
在外部类内,不使用static关键字定义的类就是成员内部类(类比成员属性和成员方法)
成员内部类需要依赖外部类的对象:先有外部类对象,才有内部类对象。当产生内部类对象时,外部类的对象会被JVM
传入内部类中。
内部类和外部类可以方便地访问彼此的私有域:
在外部类的成员方法中,创建内部类对象,可以通过该对象访问内部类的成员变量和成员方法。
成员内部类的成员方法可以通过外部类名.this调用外部类的方法和属性。
成员方法可以访问成员变量和静态变量,不能定义静态变量;静态方法可以访问静态变量,不能访问成员变量
成员内部类能否访问外部类中的静态域?
能。成员内部类中有外部类的对象,通过该对象可以访问外部类的静态域
成员内部类能否在其内部定义静态域?
不能。
假设成员内部类中有静态域,例如静态属性,该属性不用产生对象也能访问。这样一来,成员内部类不用产生对象(也就不用先产生外部类对象)就能产生,与成员内部类必须依赖外部类对象才能产生的条件相悖。所以,在成员内部类中,不能存在静态域!!!
成员内部类产生对象的两种方式
-
在外部类内产生内部类对象
Inner inner = new Inner();
-
若内部类对外部可见(不是private修饰),在外部类外产生内部类对象
Outter是外部类 Inner是内部类 //在Outter外部产生内部类对象 Outter.Inner inner = new Outter().Inner();
静态内部类
使用static
关键字定义在一个类内部的类
静态内部类不需要依赖于外部类的对象就能产生,和外部类是一个相对独立的关系,只是定义在了外部类的内部。静态内部类:类比类中的静态属性或静态方法。
静态内部类由于在其内部没有外部类的对象,无法直接访问外部类的成员域(需要外部类的对象才能访问);可以直接访问外部类的静态域。
静态内部类中能否定义自己的成员域?
能。静态内部类就是一个普通类,只不过是套在一个类的内部而已。
方法内部类
定义在方法中,类比方法中的局部变量
class Outter {
public void fun() {
class Inner {
}
}
}
- 不能使用任何权限修饰符,只在方法的作用域内有效,出了此方法,该方法内部类就不存在了。
- 对外部类的外部完全隐藏
- 方法内部类(Inner)要使用其所在方法(fun方法)的形参或者局部变量,则:该变量必须为隐式的final声明。—→只能在方法内部类中读取该变量,无法修改。
- 在方法内部类中使用过的方法的局部变量(包括形参和方法的局部变量),其在方法内部不可被修改。
匿名内部类(Lambda表达式)
定义在方法的参数(形参或实参,实参居多)上,也是方法内部类的一种。
内部类存在的原因
内部类和外部类可以方便地访问彼此的私有域
内部类可以对外部类的外部完全隐藏(通过使用private修饰内部类)
内部类可以变相实现多继承(不推荐这样做)
class A{} class B{} //在类C中,同时具有A与B的内容 class C { class InnerA extends A { } class InnerB extends B { } }
Lambda表达式
2008年(大数据最火热的阶段,函数式编程思想),JDK8发布
Java的面向对象的定义太繁琐,在处理各种数学运算时频繁需要定义类、方法。
JDK8发布了Lambda表达式
JDK8之后,接口中不仅只有抽象方法和全局常量,还可以有default普通方法。
default关键字在接口中表示普通方法,不能省略!不写default则认为该方法是抽象方法。
Spring5即将不再支持JDK8,只支持JDK11+
函数式接口
一个接口有且仅有一个抽象方法
在接口前使用
@FunctionalInterface
检查当前接口是否是函数式接口
Lambda表达式
能使用Lambda表达式的匿名内部类,必须是实现了一个函数式接口。在方法的实参处,仅保留匿名内部类要覆写的方法参数(),->代表实现的意思,还保留方法体{具体实现}。
Lambda表达式的四种情况
对应接口中的抽象方法的四种类型
-
若{接口中抽象方法的实现}仅有一行代码,则可以省略{},变为:
() -> 实现代码
-
若抽象方法的参数只有一个,则Lambda表达式可以省略:()以及其内部参数的类型。
//抽象方法的定义为: void func(int x); (int x) -> {} //上述写法可以省略为: x -> {} //() 和 int须一起省略
无返回值、无参
无返回值、有参
有返回值、无参
有返回值、有参