内部类:定义在类内部的类
内部类分为:静态内部类、成员内部类、局部内部类、匿名内部类
1、静态内部类
定义在类内部的静态类
public class Out {
private static int a;
private int b;
public static class Inner {
public void print() {
System.out.println(a);
}
}
}
1.静态内部类可以访问外部类的所有静态的变量和方法,包括private的。(不能访问非静态的)
public static class Inner {
public void print() {
System.out.println(a);
// System.out.println(b); 不能访问非静态的成员变量
}
}
2.静态内部类和一般类一样,也可以定义静态变量、方法、构造方法
3.其它类使用静态内部类需要使用“外部类.静态内部类”方式,例如:
Out.Inner inner = new Out.Inner();
inner.print();
2、成员内部类
定义在类内部的 非 静态内部类
public class Out {
private static int a;
private int b;
public class Inner {
private static int c;
public void print() {
System.out.println(a);
System.out.println(b);
}
}
}
1.成员内部类不能定义静态变量和方法,final修饰的除外
2.这是因为成员内部类是非静态的,类初始化的时候会先初始化静态成员。如果允许成员内部类定义静态变量,就和成员内部类的静态变量初始化顺序有歧义
3、局部内部类
定义在方法中的类
public class Out {
private static int a;
private int b;
public void test(final int c) {
final int d = 0;
class Inner {
public void print() {
System.out.println(c);
}
}
}
}
1.如果一个类只在某个方法中使用,可以考虑用局部内部类
4、匿名内部类
匿名内部类我们必须要继承一个父类或者实现一个接口,当然也仅能只继承一个父类或者实现一
个接口。同时它也是没有 class 关键字,这是因为匿名内部类是直接使用 new 来生成一个对象的引用。
1.实现接口
public interface Greeting {
void sayHello();
}
public class AnonymousInnerClassExample {
public static void main(String[] args) {
// 定义并实例化一个匿名内部类来实现 Greeting 接口
Greeting greeting = new Greeting() {
@Override
public void sayHello() {
System.out.println("Hello!");
}
};
// 调用匿名内部类实现的方法
greeting.sayHello();
}
}
在上述代码中,new Greeting() {... }
定义了一个匿名内部类,它实现了Greeting
接口,并在大括号内实现了接口的sayHello
方法。
2.继承抽象类
abstract class Animal {
abstract void makeSound();
}
public class AnonymousInnerClassExample2 {
public static void main(String[] args) {
// 定义并实例化一个匿名内部类来继承 Animal 抽象类
Animal dog = new Animal() {
@Override
void makeSound() {
System.out.println("Woof!");
}
};
// 调用匿名内部类实现的方法
dog.makeSound();
}
}
这里,new Animal() {... }
定义了一个匿名内部类,它继承了Animal
抽象类,并实现了抽象方法makeSound
。
注意事项
- 语法限制:匿名内部类没有构造函数,因为它没有类名。
- 作用域:匿名内部类的作用域仅限于定义它的地方。
- 局部变量访问:匿名内部类访问外部方法的局部变量时,该变量必须是
final
(Java 8 之前)或事实上的final
(Java 8 及以后)。
通过使用匿名内部类,可以使代码更加简洁,尤其是在只需要创建一个简单的、一次性使用的类时。