本文已参与「新人创作礼」活动,一起开启掘金创作之路。
在 Java 中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类(不介绍) 和 静态内部类。
一、简要介绍
内部类基本格式:
Public class ClassOut{ //外部类
class ClassIn{ //内部类
}
}
1、成员内部类
使用示例进行介绍,并介绍其一些性质:
public class ClassOut {
int a; //外部类中的成员变量
private int b; //外部类中的私有成员变量
static int c; //外部类中的静态成员变量
public void print1() { //外部类中的方法
b = 1;
System.out.println("b=" + b );
}
public static void print2(){ //外部类中的静态方法
System.out.println("c=" + c );
}
public void print3() { //内部类中的方法
System.out.println("外部类中的print方法");
}
class ClassIn{ //成员内部类
int d; //内部类中的成员变量
public void print3() { //内部类中的方法
System.out.println("内部类中的print方法");
}
public void printIn1(){
//内部类可直接访问外部类中的任意成员
b = 2;
c = 3;
print1();
print2();
}
public void printIn2(){
//内部类和外部类有相同名称成员时,优先访问内部类自己的成员
System.out.print("优先调用:");
print3();
//如果要访问外部类的成员时,必须使用:外部类名称.this.同名成员名字
System.out.print("访问外部类成员:");
ClassOut.this.print3();
}
}
public static void main(String[] args) {
ClassOut classOut = new ClassOut();
System.out.println(classOut.a);
System.out.println(classOut.b);
System.out.println(classOut.c);
classOut.print1();
classOut.print2();
classOut.print3();
System.out.println("<<<<<<<<<<<<<<<我是分割线>>>>>>>>>>>>>>>");
//以下两种方式创建内部类对象均可
//创建内部类对象必须借助外部类对象
ClassOut.ClassIn classIn1 = new ClassOut().new ClassIn();
ClassOut.ClassIn classIn2 = classOut.new ClassIn();
classIn1.printIn2(); //测试同名方法是否优先调用内部类的方法
}
}
成员内部类的方法中包含一个指向外部类对象的引用
this$0
2、局部内部类(不常使用)
定义在方法体内部,只能在方法体内使用。
public class ClassOut {
public void method() {
class ClassIn{
public void methodClassIn(){
System.out.println("局部内部类");
}
}
ClassIn classIn = new ClassIn(); //只能在方法体内使用
classIn.methodClassIn();
}
public static void main(String[] args) {
classOut.ClassIn classIn = null;
}
}
3、静态内部类
被static修饰的内部成员称为静态内部类。
public class ClassOut {
int a;
private int b;
static int c;
public void method1() {
System.out.println("ClassOut.method1");
}
public static void method2(){
System.out.println("ClassOut.method2");
}
static class ClassIn{ //静态内部类
public void methodIn(){
//内部类中只能访问外部类的静态成员变量
//a = 10; 非静态变量,编译失败
//b = 100; 非静态变量,编译失败
c = 20;
//method1(); //非静态方法
method2();
}
}
public static void main(String[] args) {
//静态内部类对象创建及访问
ClassOut.ClassIn classIn = new ClassOut.ClassIn();
classIn.methodIn();
}
}
附: 外部类和内部类公用一个java源文件,但是经过编译后,内部类会生成单独的字节码文件。
二 、使用场景及好处
- 每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类使得多继承的解决方案变得完整。
- 方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏。
- 方便编写事件驱动程序。
- 方便编写线程代码。