内部类
1. 非静态内部类
2. 静态内部类
这上面两个需要使用import引入
3. 匿名内部类
非静态内部类
定义格式
class Inside {....}
- 非静态内部类中不能有静态成员
因为类的加载顺序是:加载类—加载静态块—等待创建实例—加载实例成员;
所以如果非静态内部类中有静态成员,那么系统在加载外部类的时候是没有加载非静态内部类的,
但如果这个内部类中有静态成员系统需要加载静态成员但是这个静态成员是在非静态内部类中,这样就产生了异常。
import project2.Extern.Del;
class Extern {
private String s = "外部类s";
public Extern() {
System.out.println("执行外部类构造器.....");
}
class Del {
public String s = "非静态内部类";
public Del() {
System.out.println("执行非静态内部类的构造器........");
}
//其中Extern.this是外部类的引用指针 this是内部类的引用指针
//非静态内部类能访问外部类的成员,但是外部类不能访问内部类的实现细节(除非外部类有内部类的实例)
public void print() {
System.out.println(Extern.this+" "+this);
}
public void test() {
System.out.println(Extern.this.s+" "+this.s);
}
}
}
public class Main {
public static void main(String[] args) {
}
}
非静态内部类的实例一定是寄生在外部类的实例中,也就是说有一个非静态内部类的实例那么肯定有外部类的实例存在
静态内部类
定义格式
static class Inside {
}
根据静态块中不能引用非静态语句,所以静态内部类中不能出现外部类中非静态的东西
(实质上就是静态内部类中不存在外部类的引用,这样也就没办法访问外部类的实例成员,从另一个角度来说,静态内部类的实例可以独立存在,不用寄生在外部类的实例中)
import project2.Extern.*;
class Extern {
static class Inside {
public static String s = "123";
public void print() {
System.out.println(this);
//Extern.this不存在
// System.out.println(Extern.this);
}
}
}
public class Main {
public static void main(String[] args) {
System.out.println(Inside.s);
Inside in = new Inside();
in.print();
}
}
匿名内部类
定义格式
new 实现接口()|父类{
.......
}
示例
interface infa {
void print();
}
class Test {
public Test(int a) {
System.out.println(a);
}
public Test(int a, int b) {
System.out.println(a+" "+b);
}
}
public class Main {
public static void main(String[] args) {
//1
infa a = new infa() {
@Override
public void print() {
System.out.println("print");
}
};
a.print();
//2
new infa() {
@Override
public void print() {
System.out.println("print");
}
}.print();
//3
java.util.Scanner in = new java.util.Scanner(System.in);
var b = new Test(in.nextInt()) {};
var c = new Test(in.nextInt(), in.nextInt()) {};
}
}
这是以上代码的反编译文件,可以帮助理解提取码: 3iyz
- 注意
- 匿名内部类不能定义构造器(匿名内部类没有类名)
- 匿名内部类不能是抽象类(匿名内部类是必须实例化的)