一.内部类概念
1.什么是内部类?
所谓的内部类就是将一个类嵌套到了另一个类的内部的操作(可以把内部类当成当前类中的一个普通属性来看待)。
内部类的设计也是一种封装的思想(体现了保护性和易用性)private只是实现属性的封装
2.内部类存在的原因(特点):
- 内部类和外部类可以方便的访问彼此的私有域(属性和方法)
- 内部类可以对外部类的外部完全隐藏(把内部类就当做外部类的属性来看待)内部类可以使用private关键字
- 内部类可以变相实现多继承
二、内部类分类
内部类 | 成员内部类 |
静态内部类 | |
方法内部类 | |
匿名内部类 |
三、成员内部类
成员内部类:(定义在类中)在外部类的内部不使用static关键字定义的内部类就是成员内部类(类比成员属性和成员方法)
1.成员内部类依赖外部类对象,先有外部类对象,才能产生内部类对象。
2.成员内部类可以直接访问外部类的私有成员属性。
public class Outter {
private String msg = "Outter中的msg属性";
private static int age = 0;
public void fun(){
System.out.println("outter的fun方法");
//外部类也可以访问内部类的私有属性,不过要先产生内部类的对象,此对象调用内部类的私有属性
Inner inner = new Inner();
//产生内部类对象
inner.test();
System.out.println(inner.innerMsg);
}
//-----------------我是分割线-----------------------------------------
//成员内部类(包访问权限) ,,不加static关键字
//若在class前加上private关键字,则该内部类为私有内部类,对于外部类的外部完全隐藏
class Inner{
private String innerMsg = "Inner类中的msg属性";
public void test(){
System.out.println("inner的test方法");
//内部类访问自身的私有属性
System.out.println(innerMsg);
//内部类也可以在其类内部直接访问外部类的私有属性
System.out.println(msg);
}
}
//-----------------我是分割线-----------------------------------------
public static void main(String[] args) {
Outter outter = new Outter();
outter.fun();
}
}
成员内部类产生对象的两种方式:
a. 在外部类的内部产生成员内部类对象:在Outter-外部类的内部产生Inner-内部类对象:
内部类名称 内部类引用 = new 内部类对象();
b. 若内部类对外部可见(不是private修饰的内部类),在外部类的外部创建内部类对象:
外部类名称.内部类名称 内部类引用= new 外部类().new 内部类();
Outter.Inner inner = new Outter().new Inner();
问:成员内部类能否访问外部类的静态域?能否定义自己的静态域?
成员内部类类似成员方法 ,成员方法可以访问类中的成员变量和静态变量,但不能定义静态变量,成员内部类可以访问外部类中的所有域(静态域、成员),因为成员内部类依赖外部类的对象,但不能在当前内部类中自己定义静态域。
成员内部类中已经拥有了外部类的对象,都有对象了,当然可以访问外部类的静态域。
成员内部类不能定义自己的静态域,假设可以,静态属性不需要对象就能调用,但是内部类必须先依赖外部类的对象才能产生-----相悖!!!
四、静态内部类
静态内部类:(定义在类中)使用static关键字定义在另一个类的内部的类。
和成员内部类最大的区别:静态内部类不需要外部类的对象。和外部类是一个相对独立的关系,只是套在外部类的内部定义而已。
静态内部类只能访问外部类的静态域,没有外部类对象,无法直接访问外部类的成员域。
问:静态内部类能否定义自己的成员域?
可以。静态内部类就是一个普通类,只是套在了另一个类的内部而已。因此可以定义自己的成员域,但是不能直接访问外部类的成员域(需要外部类对象)。
五、方法内部类
方法内部类:定义在方法中的类。
方法内部类的特点:
- 不能使用任何权限修饰符(这个类出了方法就没了)
- 对外部完全隐藏(外部类的外部)
- Inner内部类要使用fun方法的形参或者局部变量,该变量必须为隐式的final声明。方法内部类要使用外部方法中的形参或者局部变量,只有读取权,没有修改权。
- 若方法内部类中读取了方法中的局部变量(形参或者局部变量),这个局部变量就无法修改(不仅在内部类中无法修改,在方法中也不能改。)
- 在Java方法以及方法内部中都不能定义静态域。
六、匿名内部类
匿名内部类(lambda表达式):匿名内部类也是方法内部类的一种,定义在方法中((方法的形参或者实参)- 实参用的最多)没有任何权限修饰符,甚至连类名称都没有的内部类。
七、Lambda表达式
1.使用Lambda表达式的前提:函数式接口
一个接口有且只有一个抽象方法,这种接口称之为函数式接口。
使用@FuncationalInterface检查当前接口是否是函数式接口。
2.Lambda表达式的前身-匿名内部类
Lambda表达式把匿名内部类中多余的new方法定义之类的全都省略了,只保留了方法的参数和方法体的实现。
能使用Lambda表达式的前提就是接口必须是函数式接口,只有唯一的一个抽象方法。
3.Lambda表达式的四种情况-对应抽象方法的四种分支
1.无返回值无参数
规则1:若方法体只有一行代码,可以省略{ }
2.无返回值有参数
规则2:若方法的参数只有一个,可以省略小括号和类型(一体的)
规则3:可以省略Lambda 表达式中参数的类型,若省略类型,都需要省略,但不能省略()
3.有返回值无参数
规则4:若抽象方法存在返回值,且覆写的方法体只有一行,此时方法体的{ }以及return关键字都可以省略。