常用类-内部类
在千锋教育的学习笔记
内部类
概念
在一个类的内部在定义一个完整的类
特点
-
内部类可以直接访问外部类的私有成员,且不破坏封装
public class Outer01 { private String name = "肖枫"; private int age = 18; class Inner{ private String sex = "男"; public void Play(){ System.out.println(name + " plays CF well!"); System.out.println(sex); } } } -
编译之后生成独立的字节码文件
![]()
-
可为外部类提供必要的内部功能组件
分类

成员内部类
-
概念
- 在类的内部定义 ,与实例变量、实例方法同级别的类
-
特点
-
外部类的一个实例部分,创建内部类对象时必须依赖外部类对象,否则会报错:“is not an enclosing class”
package com.ciao.innerDemo; import com.ciao.innerDemo.Outer01.Inner;//先导入内部类(为什么?) public class Test01 { public static void main(String[] args) { //创建外部类对象 Outer01 outer = new Outer01(); //创建内部类对象 Inner inner = outer.new Inner(); //Inner inner = new Outer01().new Inner();//一步完成 inner.Play();//调用内部类中的共有方法 } } -
当内部类、外部类存在同名属性时,会优先访问内部类的属性
public class Outer01 { private String name = "肖枫"; private int age = 18; class Inner{ private String sex = "男"; private String name = "麒麟"; public void Play(){ System.out.println(name + " plays CF well!");//访问内部类 System.out.println(this.name + " plays CF well!");//当前类 System.out.println(Outer01.this.name + " plays CF well!");//外部类 System.out.println(sex); } } }-
直接调用外部类的私有属性报错:Non-static method '*' cannot be referenced from a static context,https://blog.csdn.net/u013642500/article/details/80156306
System.out.println(Outer01.name + " plays CF well!");//直接调用外部类的私有属性时报错
-
-
-
成员内部类中不能定义静态成员,但可以定义静态常量
private static String name = "麒麟";//会报错(Inner classes cannot have static declarations) private static final String name = "麒麟";//定义静态常量
静态内部类
-
概念
- 在类的内部定义 ,与外部类同级别的类(相当于一个外部类)
-
特点
-
不依赖外部类对象,可直接创建或通过类名访问,可声名静态成员。
package com.ciao.innerDemo02; public class Outer { private String name = "肖枫"; private int age = 18; static class Inner{//静态内部类,在内部类前添加一个static修饰 private String sex = "男"; private String name = "麒麟"; private static int count = 10;//静态成员 public void Play(){ //相当于一个外部类调用Outer类中的属性 // 需要先创建实例,再通过实例调用属性 Outer outer = new Outer();//创建外部实例 System.out.println(this.name + " plays CF well!");//调用实例属性 System.out.println(name + " plays CF well!"); System.out.println(outer.name + " plays CF well!"); System.out.println(count); } } }
-
-
注意
- 只有内部类才能用
static修饰,普通类不可以。
- 只有内部类才能用
局部内部类
-
概念
-
类似于局部变量,定义在外部类的方法中,作用范围和创建对象范围仅限于当前方法中
-
定义类
package com.ciao.innerDemo03; public class Outer { //外部类属性 private String name = "肖枫"; private int age = 19; public void show(){ //定义局部变量(问:只能用final修饰?)(答:jdk1.7要求变量必须是常量final,jdk1.8自动添加final) String sex = "男"; //定义局部内部类,不能加任何访问修饰词 class Inner { //定义局部内部类的属性 private String phone = "15333333333"; public void InnerShow() { System.out.println(Outer.this.name);//直接访问外部类属性 System.out.println(sex);//直接访问方法中的局部变量,jdk1.7要求变量必须是常量final,jdk1.8自动添加final System.out.println(this.phone); } } //在方法中创建局部内部类对象 Inner inner = new Inner(); inner.InnerShow();//调用方法 } }思考:上述
sex变量为什么要加final修饰符?(https://www.bilibili.com/video/BV1vt4y197nY?p=6 11:05 内部类中访问的sex已经变成确定的值"男"了) -
测试
package com.ciao.innerDemo03; public class Test { public static void main(String[] args) { Outer outer01 = new Outer();//通过外部类实例调用局部内部类 outer01.show(); } }
-
-
-
特点
-
局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为
finalpublic class Outer { //外部类属性 private String name = "肖枫"; private int age = 19; public void show(){ //定义局部变量(问:只能用final修饰?)(答:jdk1.7要求变量必须是常量final,jdk1.8自动添加final) String sex = "男"; //定义局部内部类,不能加任何访问修饰词 class Inner { //定义局部内部类的属性 private String phone = "15333333333"; public void InnerShow() { System.out.println(Outer.this.name);//直接访问外部类属性 System.out.println(sex);//直接访问方法中的局部变量,jdk1.7要求变量必须是常量final,jdk1.8自动添加final System.out.println(this.phone); } } //在方法中创建局部内部类对象 Inner inner = new Inner(); inner.InnerShow();//调用方法 } } -
局部内部类中不能包含静态成员,但可用
final修饰静态成员变成静态常量private static int count = 1;//Inner classes cannot have static declarations private final static int count = 1; -
限制类的使用范围,只能在方法中使用
-
匿名内部类
-
概念
- 没有类名的局部内部类(一切特征都与局部内部类相同)
-
特点
- 必须继承一个父类或者实现一个接口
- 定义类、实现类、创建对象的语法合并,只能创建一个该类的对象
-
优缺点
- 优点:减少代码量
- 缺点:可读性较差
-
案例
-
接口
package com.ciao.innerDemo04; //接口 public interface Usb { //服务 void Service(); } -
鼠标类
package com.ciao.innerDemo04; //鼠标实现usb接口 public class Mouse implements Usb{ //实现方法 @Override public void Service() { System.out.println("连接成功,鼠标开始工作..."); } } -
测试类
package com.ciao.innerDemo04; public class TestUsb { public static void main(String[] args) { // Usb usbMouse = new Mouse();//创建接口类型的变量 // usbMouse.Service(); /* //局部内部类 class Windy implements Usb{ //风扇 @Override public void Service() { System.out.println("连接成功,风扇开始工作..."); } } //使用局部内部类创建对象 Usb usbWindy = new Windy(); usbWindy.Service(); */ //使用匿名内部类优化(相当于创建了一个局部内部类) Usb usbKey = new Usb() {//可以是接口,也可以是抽象类或者父类,在里面重写方法就行 @Override public void Service() { System.out.println("连接成功,键盘开始工作..."); } }; usbKey.Service(); } } -
匿名函数其实也有名字,系统命名的,查看输出文件
![]()
-
欲买桂花同载酒,终不似,少年游~


浙公网安备 33010602011771号