Java基础之——内部类的基本使用
内部类概述
定义:内部类就是在一个类的内部再定义一个类
内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量
内部类分为:
- 成员内部类
- 静态内部类
- 局部内部类
- 匿名内部类
成员内部类
在一个类中使用内部类,可以在内部类中直接存取其所在类的私有成员变量,但外部类不能直接访问内部类成员变量
语法:
public class OuterClass {
private class InnerClass {
...
}
}
- 内部类可以访问外部类的成员,即便是private的
- 外部类无法访问内部类的成员,但可以用内部类对象调用
- 可以在外部类中创建内部类对象
- 内部类的对象实例化操作必须在外部类或外部类的非静态方法中实现
- 在非静态内部类中不可以声明静态成员
内部类的实例一定要绑定在外部类的实例上,如果从外部类中初始化一个内部类对象,那么内部类对象就会绑定在外部类对象上
想访问内部类,需要通过外部类来实例化内部类
外部类的名称:Body$Heart.class
public class OuterClass {
//外部类 实例化 内部类对象引用
innerClass in = new innerClass();
public void ouf() {
//在外部类方法中调用内部类方法
in.inf();
}
//内部类
class innerClass {
//内部类成员变量
int y = 0;
//内部类构造方法
innerClass() {}
//内部类成员方法
public void inf() {}
}
//外部类方法,返回内部类引用
public innerClass doit() {
//报错
y = 4;
in.y = 4;
//返回内部类引用
return new innerClass();
}
public static void main(String args[]) {
OuterClass out = new OuterClass();
//内部类的对象实例化操作必须在外部类或外部类的非静态方法中实现
OuterClass.innerClass in = out.doit();
OuterClass.innerClass in2 = out.new innerClass();
//外部类名.内部类名 对象变量名 = new 外部类名().new 内部类名();
OuterClass.innerClass inner = new OuterClass().new innerClass();
}
}
关于内部类与外部类成员变量重名
public class Outer {
private int x;
private class Inner {
private int x;
public void doit(int x) {
x++; //形参
this.x++; //内部类x
Outer.this.x++; //外部类x
}
}
}
静态内部类
静态内部类:用static修饰的内部类
- 静态内部类只能访问外部类中的静态成员
- 不可以使用外部类的非静态成员
public class Outer {
private int id = 1;
public void out() {
}
//静态内部类
public static class Inner {
public void in() {
}
}
}
局部内部类
写在成员方法中的类
使用范围:只有当前所属的方法才能使用它,出了方法就不能用了
public class Outer {
public void method() {
//局部内部类
class Inner {
}
}
}
局部内部类中,如果希望访问所在方法的局部变量,这个局部变量必须是有效final的
public class Outer {
public void method() {
final int num = 10;
//或者 int num = 10;但之后不能改变num的值
class Inner {
public void Method() {
System.out.println(num);
}
}
}
}
匿名内部类
使用场景:接口的实现类(或者是父类的子类)只需要使用唯一的一次
作用:没有命名的内部类,通常用来简化代码编写,只能使用一次
前提条件:必须继承一个父类或实现一个接口
编译后内部类的.class文件的命名规则如下:
- 一般内部类:外部类名 $ 内部类名
- 匿名内部类:外部类名 $ 数字
书写规则:
public class Outer {
public static void main(String[] args) {
MyInterface obj = new MyInterface() {
@Override
public void method() {
}
};
}
}
interface MyInterface {
void method();
}