废话不多讲直接上代码
//声明一个接口供匿名内部类使用,也可以是抽象类和类ps:如果是类的话扩充类的方法和变量
interface A {
public void p();
}
public class InnerClass {
// 非静态方法
private final String name = "Inner";
// 静态方法
private static String sname = "SInner";
public String p() {
return "我是外部类非静态方法";
}
public static String pp() {
return "我是外部类静态方法";
}
public void overTest() {
System.out.println("外部类测试覆写的方法!");
}
// 成员内部类---可以访问外部类的所有静态非静态方法和属性,当然包括final修饰的属性和方法
class InnerC {
// 允许全局内部类常量使用
static final int a = 3;
// static int a=2;--->会报错,成员内部类因为是非静态内部类,不允许使用static修饰但可以使用static
// final修饰变量
// 成员内部类覆写外部类方法看执行哪个方法
public void overTest() {
System.out.println("成员内部类覆写外部类方法!");
}
public void foo() {
System.out.println("成员内部类方法!");
}
// public static final void fo() { System.out.println("成员内部类静态方法!"); }--->会报错,成员内部类因为是非静态内部类,不允许static修饰方法
// 构造方法
public InnerC() {
System.out.println("外部类非静态变量访问:" + name + "外部类非静态方法访问" + p());
System.out.println("外部类静态变量访问:" + sname + "外部类静态方法访问" + pp());
}
}
// 静态内部类 ---只能访问外部类的静态方法和静态属性,当然包括final修饰的静态方法和属性
static class InnerSC {
// 静态内部类覆写外部类方法看执行哪个方法
public void overTest() {
System.out.println("静态内部类覆写外部类方法!");
}
public void foo() {
System.out.println("静态内部类方法!");
}
public static void fo() {
System.out.println("静态内部类静态方法!");
}
public InnerSC() {
// System.out.println("外部类非静态变量访问:" + name + "外部类非静态方法访问" +p());//--->会报错不能访问非静态方法
System.out.println("外部类静态变量访问:" + sname + "外部类静态方法访问" + pp());
}
}
// 局部内部类---可以访问外部类的所有静态非静态方法和属性,当然包括final修饰的外部类的属性和方法,但是只能访问方法内部final修饰的变量
public void fo() {
int i = 3;
final int j = 5;
// static int k=8;---非法的表达式,方法里面不允许static final static int a=10;---非法的表达式,方法里面不允许static
class InnerFC {
public InnerFC() {
System.out.println("外部类非静态变量访问:" + name + "外部类非静态方法访问" + p());
System.out.println("外部类静态变量访问:" + sname + "外部类静态方法访问" + pp());
// System.out.println("访问方法中变量:"+i);---不能引用方法里面的非final修饰的变量
System.out.println("访问方法中final修饰的变量:" + j);
}
public void pfoo() {
System.out.println("局部内部类方法");
}
// 覆写外部类看看调用的是哪个方法
public void overTest() {
System.out.println("覆写外部类的方法!");
}
}
// 实例化局部内部类,如果此处不是实例化,此局部内部类将就是一片代码会被编译但不会被执行,外部类不能实例化此类
InnerFC iFc = new InnerFC();
// 调用局部内部类的方法
iFc.pfoo();
// 调用覆写外部类后的局部内部类的方法
iFc.overTest();
}
// 匿名内部类---可以访问外部类的所有静态非静态方法和属性,当然包括final修饰的属性和方法,创建一个临时在堆内存中的对象,只使用一次即可能被jvm销毁
public void foo(A a) {
System.out.println("外部类非静态变量访问:" + name + "外部类非静态方法访问" + p());
System.out.println("外部类静态变量访问:" + sname + "外部类静态方法访问" + pp());
}
public static void main(String[] args) {
// 匿名对象访问成员内部类
new InnerClass().new InnerC();
// 正常访问成员内部类
InnerClass iClass = new InnerClass();
InnerClass.InnerC innerC = iClass.new InnerC();
// 访问静态内部类的静态内部方法--->ps:因为是静态内部类所以不能像上面的成员内部类那样的实例化静态内部类会报错的噢,因为静态内部类不能new所以只能这种方式访问静态内部类的静态方法
InnerClass.InnerSC.fo();
// 访问静态内部类的内部非静态方法--->ps:因为静态内部类不能new所以只能这种方式访问静态内部类的非静态方法
new InnerClass.InnerSC().foo();
// 匿名对象访问局部内部类方
new InnerClass().fo();
// 正常访问局部内部类
InnerClass iClass2 = new InnerClass();
iClass2.fo();
// 匿名对象访问匿名内部类方式1
new InnerClass().foo(new A() {
@Override
public void p() {
System.out.println("我是匿名内部类!");
}
});
// 正常访问匿名内部类
InnerClass iClass3 = new InnerClass();
iClass3.foo(new A() {
@Override
public void p() {
System.out.println("我是匿名内部类!");
}
});
}
}
运行结果:
外部类非静态变量访问:Inner外部类非静态方法访问我是外部类非静态方法外部类静态变量访问:SInner外部类静态方法访问我是外部类静态方法
外部类非静态变量访问:Inner外部类非静态方法访问我是外部类非静态方法
外部类静态变量访问:SInner外部类静态方法访问我是外部类静态方法
静态内部类静态方法!
外部类静态变量访问:SInner外部类静态方法访问我是外部类静态方法
静态内部类方法!
外部类非静态变量访问:Inner外部类非静态方法访问我是外部类非静态方法
外部类静态变量访问:SInner外部类静态方法访问我是外部类静态方法
访问方法中final修饰的变量:5
局部内部类方法
覆写外部类的方法!
外部类非静态变量访问:Inner外部类非静态方法访问我是外部类非静态方法
外部类静态变量访问:SInner外部类静态方法访问我是外部类静态方法
访问方法中final修饰的变量:5
局部内部类方法
覆写外部类的方法!
外部类非静态变量访问:Inner外部类非静态方法访问我是外部类非静态方法
外部类静态变量访问:SInner外部类静态方法访问我是外部类静态方法
外部类非静态变量访问:Inner外部类非静态方法访问我是外部类非静态方法
外部类静态变量访问:SInner外部类静态方法访问我是外部类静态方法
总结:
成员内部类:可以访问所有外部类变量方法,且内部不能定义static的方法和变量但可以定义static final的变量(内部类全局常量)静态内部类:可以访问所有外部类静态方法和变量
局部内部类:可以访问所有外部类变量方法,只能访问定义在方法中的final变量
匿名内部类:可以访问所有外部类静态方法和变量
注意调用的方式:
成员内部类 new OutClass().new InnerClass();
静态内部类只能访问方法,且只能是匿名对象访问
静态方法---> OutClass.InnerSClass.foo();
非静态方法--->new OutClss.InnerSclass().foo();
局部内部类:只能在方法内部实例化并调用
匿名内部类:在括号中实例化