一、内部类
将一个类定义在另一个类或者一个方法的内部, 前者称为内部类,后者称为外部类 。内部类也是封装的一种体现在外部类中,内部类定义位置与外部类成员所处的位置相同,因此称为成员内部类。public class OutClass {class InnerClass {}}// OutClass 是外部类// InnerClass 是内部类根据内部类定义的位置不同,一般可以分为以下几种形式:1. 成员内部类 ( 普通内部类:未被 static 修饰的成员内部类 和 静态内部类:被 static 修饰的成员内部类 )2. 局部内部类 ( 不谈修饰符 ) 、匿名内部类
1.实例内部类:即未被static修饰的成员内部类。
1. 可以在实例内部类方法中 直接访问 外部类中的任何成员2. 实例内部类所处的位置与外部类成员位置相同,因此也受 public 、 private 等访问限定符的约束3. 在实例内部类方法中访问同名的成员时, 优先访问自己的 ,如果要 访问外部类同名 的成员,必须: 外部类名称.this.同名成员 来访问4. 必须在 先有外部类对象 前提下, 才能创建实例内部类对象5. 实例内部类的非静态方法中包含了一个指向外部类对象的引用6. 外部类中,如果要访 问实例内部类中的成员 ,必须 先要创建内部类的对象 。
class OuterClass{//外部类基本上所有的变量都可以定义public int a = 1;public static int b = 2;private int c = 3;private static int d;protected int e;class InnerClass{//实例内部类public int a = 10;// public static int b = 10;不能创建静态变量//内部类是需要实例化对象,来使用的。而static不依赖于对象,所以不能创建变量public static final int b = 20;//加上final就变成常量了,可以使用private int d = 30;public void test(){System.out.println("InnerClass::test()");System.out.println(a);//10,实例内部类,和外部类有同名变量的时候,实例内部类优先System.out.println(OuterClass.this.b);//2,访问外部类同名变量System.out.println(c);//3,实例内部类没有该变量,去外部类找System.out.println(d);//30}}public void test(){System.out.println("OuterClass::test()");}
}
public class Test2 {public static void main(String[] args) {//不能直接实例化内部类对象//需要外部类的引用,实例化内部类对象OuterClass outerClass = new OuterClass();OuterClass.InnerClass innerClass = outerClass.new InnerClass();innerClass.test();//调用内部方法}
}
2.静态内部类:被static修饰的内部成员类称为静态内部类。
1. 在静态内部类中只能访问外部类中的静态成员如果确实想访问,我们该如何做? 提供一个外部类的引用2. 创建静态内部类对象时,不需要先创建外部类对象
class Out{public int a = 1;public static int b = 2;private int c = 3;static class InnerClass{public int d = 10;public static int e = 20;private int f = 30;public void test(){Out out = new Out();System.out.println("InnerClass::test()");System.out.println(out.a);//静态类不能直接访问非静态类的成员System.out.println(b);System.out.println(out.c);//静态类不能直接访问非静态类的成员//自己内部的成员可以直接访问System.out.println(d);System.out.println(e);System.out.println(f);}}public void test(){System.out.println("OuterClass::test()");}
}
public class Test2 {public static void main(String[] args) {Out.InnerClass innerClass = new Out.InnerClass();innerClass.test();}}
3.局部内部类:定义在外部类的方法体或者{}中,该种内部类只能在其定义的位置使用
1. 局部内部类 只能在所定义的方法体内部使用2. 不能被 public 、 static 等修饰符修饰3. 编译器也有自己独立的字节码文件,命名格式:外部类名字 $ 数字内部类名字 .class4. 几乎不会使用(一般使用的非常少)
public class Test2 {public void func(){class InnerClass{public int a = 1;}InnerClass innerClass = new InnerClass();System.out.println(innerClass.a);}public static void main(String[] args) {Test2 test2 = new Test2();test2.func();}
}
4.匿名内部类
interface IA{void test();
}
public class Test2 {public static void main(String[] args) {//相当于一个类实现了IA接口,重写了test这个方法
//方法1new IA(){@Overridepublic void test() {System.out.println("这是重写了接口的方法!");}}.test();}//方法2IA ia = new IA() {@Overridepublic void test() {System.out.println("这是重写了接口的方法!");}};ia.test();}