package com.exercise;
/*
在一个类的内部定义的类,称为内部类,
编译生成的class文件中外部类和内部类之间通过'$'连接
内部类可以重写外部类的方法,并在内部类之间使用!?!?!?
内部类主要分类:
实例内部类
局部内部类
静态内部类
*/
public class InnerClass {
// 实例变量
private int a;
// 静态变量
private static int b;
public InnerClass(int a, int b) {
this.a = a;
InnerClass.b = b;
}
// 实例方法
public void ma() {
System.out.println("Method a");
}
// 静态方法
public static void mb() {
System.out.println("Method b");
}
/*
实例内部类
可以用public、private、protected修饰或缺省
创建实例内部类,外部类的实例必须已经创建
实例内部类会持有外部类的引用,可以访问外部类的所有变量和方法
实例内部不能定义 static 成员,只能定义实例成员
*/
// 内部类可以使用 private、protected 修饰
private class Inner1 {
int i1 = 0;
private int i2 = 1;
int i3 = a;
// static int i4 = 20; // 实例内部类不能采用 static 声明
public void ma_1() {
InnerClass c = new InnerClass(1, 2);
ma();
System.out.println("Method a1");
c.ma();
mb();
}
public void ma() {
System.out.println("重写了外部类的方法");
}
// public static void mb_1(){}; 不能定义静态方法
}
/*
静态内部类
可以等同看做静态变量,可以用public、private、protected修饰或缺省
静态内部类可以直接访问外部的静态变量,无法直接访问成员
静态内部类不会持有外部的类的引用,创建时可以不用创建外部类
*/
static class Inner2 {
int i1 = 10; // 可以定义实例变量
static int i2 = 100; // 可以定义静态变量
static int i3 = b; // 可以直接使用外部类的静态变量
// int i4 = a; // 不能直接引用外部类的实例变量
int i4 = new InnerClass(100, 200).a; //采用外部类的引用可以取得成员变量的值
// 实例(成员)方法
public void ma_2() {
System.out.println("Method a2");
// ma(); // 不可以在静态上下文中使用,也即无法直接访问外部类成员
mb();
}
// 静态方法
public static void mb_2() {
System.out.println("Method b2");
mb();
}
}
/*
局部内部类
只在方法中有效,所以不能用访问控制权限修饰符
在方法中定义的,它只能在当前方法中使用,和局部变量的作用一样。
*/
public static void m3(int temp) {
// 局部变量在内部类中使用必须采用 final 修饰!!!
// 虽然不写final也可以成功运行,但是后文中不可以修改局部变量的值
int i1 = 10;
class Inner3 {
int i2 = b; // 可以访问外部类的成员变量
// static int i3 = 0; // 不能包含静态成员
int i3 = temp;
// 实例(成员)方法
public void ma_3() {
// i1 = 20; // 局部内部类不能再修改局部变量的值!!!
System.out.println("Method a3" + i1 + temp);
// ma(); // 不可以在静态上下文中使用,也即无法直接访问外部类成员
mb();
}
// 内部类不能声明静态方法
// public static void mb_3(){}
}
// 使用内部类
Inner3 inner3 = new Inner3();
inner3.ma_3();
System.out.println("inner3 " + inner3.i2 + inner3.i3);
}
public static void main(String[] args) {
// 实例内部类创建实例语句1
InnerClass outClass = new InnerClass(100, 200);
outClass.ma();
Inner1 inner01 = outClass.new Inner1();
// 实例内部类创建实例语句2
Inner1 inner1 = new InnerClass(100, 200).new Inner1();
inner1.ma_1();
inner1.ma();
// 静态内部类创建实例语句
Inner2 inner2 = new Inner2();
inner2.ma_2();
inner2.mb_2();
// 局部内部类调用
outClass.m3(3);
System.out.println("---------------");
System.out.println(outClass.a); // 类的内部可以访问私有实例变量
System.out.println(b); // 类的内部可以访问私有静态变量
System.out.println("inner3 " + inner1.i1 + inner1.i2);
// 匿名内部类
// 不需要再单独写一个接口的实现类,直接在方法传参阶段写
noName(new MyInterface() {
@Override
public void interfaceMethod() {
System.out.println("实现抽象方法");
}
});
}
// 匿名内部类函数调用
public static void noName(MyInterface i){
System.out.println("匿名内部类" + i); // 打印输出:匿名内部类com.exercise.InnerClass$1@2c6a3f77
}
}
interface MyInterface{
void interfaceMethod();
}