Java中内部类的概念与分类详解
目录
- 内部类概念
- 内部类的分类:
- 成员内部类
- 普通内部类
- 静态内部类
- 局部内部类
- 总结
只能使用修饰限定符:public 和 默认 来修饰类
内部类概念
在 Java 中,将一个类定义在另一个类的内部,称为内部类
就是在一个类内部进行其他类结构的嵌套操作
内部类也是封装的一种体现
举例:
//外部类 public class OutClass { //内部类 class InnerClass{ } }
注意:内部类和外部类共享一个 java源文件,但是经过编译之后,会形成各自单独的字节码文件
内部类的分类:
成员内部类
在外部类中,内部类定义位置与外部类成员所处的位置相同,因此称为成员内部类
成员内部类有:普通内部类和静态内部类
普通内部类
未被 static 修饰的成员内部类
//外部类 public class OutClass { public void method(){ } //普通内部类 class InnerClass1{ } }
如何使用普通内部类??
先看普通类的使用:
package Date20210917; public class Test1 { int a; public void method1(){ } //普通内部类 class InnerClass{ int b; void method2() { } } public static void main(String[] args) { Test1 test1 = new Test1(); test1.method1(); }
普通类:先构造对象—通过对象访问类内部的成员
那么,我们可以试着 new 一个 InnerClass 的对象:
我们发现并不可行,因为 InnerClass 也是 外部类的成员,所以我们在使用内部类时,需借助外部类的对象来创建内部类的对象
则正确操作:
public static void main(String[] args) { //普通类:先构造对象—通过对象访问类 内部的成员 Test1 test1 = new Test1(); test1.method1(); //普通内部类 InnerClass innerClass = test1.new InnerClass(); innerClass.method2(); }
不同文件下 普通内部类的使用:
package Date20210917; //外部类 public class OutClass { //测试Test1 中的内部类的使用: void test(){ Test1 test1 = new Test1(); //要实例化 Test1 中内部类的对象 //InnerClass; 编译器不能识别,因为该类没在此文件中 Test1.InnerClass t = test1.new InnerClass(); } public static void main(String[] args) { } }
当内外部类出现同名变量时,使用就近原则~ 即:优先访问内部类的
public class Test1 { int a; int b; public void method1(){ } //普通内部类 class InnerClass{ int b; void method2() { a = 10; method1(); b = 66; //给内部类自己的 成员变量 b 赋值 } } }
内部类中给同名外部类成员变量赋值:
Test1.this.b = 88;
调试验证:
即:编译后,对 method2 进行以下修改
修改前:
void method2() { a = 10; method1(); b = 66; //给内部类自己的 成员变量 b 赋值 Test1.this.b = 88; }
修改后:
void method2(InnerClass this){ this$0.a = 10; method1(this$0); this.b = 66; Test1.this.b = 88; }
总结:
- 普通内部类对象必须在先有外部类对象前提下才能创建
- 外部类中,不能直接访问内部类中的成员,如果要访问必须先要创建内部类的对象
- 外部类中的任何成员都可以被在普通内部类方法中直接访问
- 在内部类方法中访问同名的成员时,优先访问自己的(就近原则),如果要访问外部类同名的成员,必须:外部类名称.this.同名成员 来访问
静态内部类
被 static 修饰的内部成员类称为静态内部类
public class Test2 { int a; int b; static int c; static void method1(){ System.out.println("我是method()"); } static class InnerClass{ int d; static int e; void method2(){ } } }
静态内部类对象的创建
1.同文件中创建:
//静态成员变量的访问 System.out.println(Test2.c); //不需要借助外部类对象来创建 InnerClass innerClass = new InnerClass();
2.不同文件里 创建:
void test2(){ //静态成员变量的访问: System.out.println(Test2.c); //静态内部类对象 (类比静态成员变量的访问) Test2.InnerClass t = new Test2.InnerClass(); //静态内部类对象可以直接创建,不需要依赖外部类对象 }
静态内部类方法里能否访问外部类的对象?
由上图可得到:在静态内部类中,只能访问外部类中的静态成员变量和静态成员方法
注意事项:
- 在内部类中只能访问外部类中的静态成员
- 在同一文件中创建内部类对象时,可以直接创建,不需要借助外部类对象
- 在不同文件中创建内部类对象时,也可直接创建:所在文件名称.内部类名称.对象名
- 成员内部类,经过编译之后会生成独立的字节码文件,命名格式为:外部类名称$内部类名称
局部内部类
定义在外部类的方法体或者 { } 中,该种内部类只能在其定义的位置使用,一般很少使用
//外部类 public class OutClass { public void method(){ //局部内部类 class InnerClass3{ } } { //局部内部类 class InnerClass4{ } } }
不能被访问修饰限定符修饰:
不能再局部内部类中定义静态成员
不能再局部内部类中定义静态方法
注意事项:
局部内部类只能在所定义的方法体内部使用不能被public、static等修饰符修饰编译器也有自己独立的字节码文件,命名格式:外部类名字$x内部类名字.class,x是一个整数 匿名内部类(这里不做讲解)
总结
到此这篇关于Java中内部类的概念与分类的文章就介绍到这了,更多相关Java内部类内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!