Java 中可以将一个类定义在另在一个类的内部,这样的类称为内部类
内部类的种类
成员内部类
成员内部类类似于成员变量,定义在类中,方法外,成员内部类包括非静态成员内部类(实例内部类)和静态成员内部类。
1、非静态成员内部类:
依赖于外部类的对象来创建其对象,可无条件访问外部类所有成员属性和成员方法,其中不能定义静态变量。在外部类中的静态方法中和外部类以外的类中必须通过外部类的实例来创建内部类的实例,其实例化语法形式如下:
外部类名.内部类名 对象名 = 外部类对象.new 内部类名();
例:
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
或者
Outer.Inner inner = new Outer().new Inner();
代码示例如下:
class Outer {
private String name;
Outer() {}
Outer(String name) {
this.name = name;
}
public void show() {
System.out.println(name);
}
// 内部类
class Inner {
public void innerShow() {
System.out.println(name); // 可直接访问外部类变量
show(); // 可直接调用外部类方法
}
}
}
测试类:
public class InnerClassDemo {
public static void main(String[] args) {
// Outer.Inner inner = new Outer().new Inner();
Outer outer = new Outer("outer class");
Outer.Inner inner = outer.new Inner();
outer.show();
inner.innerShow();
}
}
输出:
outer class
outer class
outer class
对于私有成员类 PrivateInner ,在外部类中提供一个 method 方法进行处理:
class Outer {
private String name;
Outer() {}
Outer(String name) {
this.name = name;
}
// 私有内部类
private class PrivateInner {
public void innerShow() {
System.out.println(name );
}
}
// 提供 public 方法 method 对私有内部类进行利用
public void mehtod() {
PrivateInner p = new PrivateInner();
p.innerShow();
}
}
2、静态成员内部类(static):
静态成员内部类不需要依赖于外部类实例对象来创建其实例对象,其中既可以定义实例成员也可以定义静态成员。静态成员内部类只能直接访问外部类 static 的成员变量和成员方法,若要访问外部类实例成员,则需通过外部类的实例来访问。
外部类以外的类可直接通过静态成员内部类的完整类名访问其静态成员,若要访问其实例成员,则需要通过其实例来访问。
public class InnerClassDemo {
public static void main(String[] args) {
// 直接通过完整类名创建实例,不需要依赖外部类实例
Outer.Inner in = new Outer.Inner();
// 通过静态内部类的实例访问其实例成员
System.out.println(in.a);
// 直接通过完整类名访问静态内部类的静态成员
System.out.println(Outer.Inner.b);
}
}
class Outer {
static String name = "outer class";
int num = 7;
// 静态内部类
static class Inner {
int a = 5;
static int b = 10;
// 直接访问外部类静态成员
String innerName = name;
// 通过外部类实例访问外部类实例成员
Outer o = new Outer();
int innerNum = o.num;
}
}
局部内部类
定义在方法中的类,外界无法直接使用,需要在方法中创建对象并使用。该类可直接访问外部类的成员以及方法中定义的局部变量,不能使用 public、protected、private、static 修饰符来修饰,其中不能定义静态变量。
public class InnerClassDemo {
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}
}
class Outer {
private String name = "outer class";
public void method() {
String str = "method";
class Inner {
public void show() {
System.out.println("Inner class" + "\nouter name: " + name + "\n" + str);
}
}
Inner i = new Inner();
i.show();
}
}
输出:
Inner class
outer name: outer class
method
匿名内部类
一个没有名字的局部内部类,没有名字,自然也没有构造器。使用匿名内部类的前提是存在一个类(具体类或抽象类)或者接口,匿名类本质是一个继承了已存在类或者实现了已存在接口的子类匿名对象
匿名类语法形式如下:
new 类名/接口名() {
方法重写;
};
前面说过,匿名类本质上是一个继承了已存在类或者实现了已存在接口的子类匿名对象。所以,可以利用多态的形式,让被继承类或被实现接口的引用指向匿名类对象
类名/接口名 名字 = new 类名/接口名() {
方法重写;
};
若不需多次使用该对象,也可直接按以下格式调用匿名类中方法:
new 类名/接口名() {
方法重写;
}.方法名();
案例:
public class InnerClassDemo {
public static void main(String[] args) {
new Inter() {
@Override
public void mehtod() {
System.out.println("匿名内部类测试");
}
}.mehtod();
Inter in = new Inter() {
@Override
public void mehtod() {
System.out.println("匿名内部类二次测试");
}
};
in.mehtod();
}
}
interface Inter {
void mehtod();
}
运行结果:
匿名内部类测试
匿名内部类二次测试