JAVA-SE-内部类
目录
一,实例内部类
二,静态内部类
三,局部内部类
四,匿名内部类
一,实例内部类
实例内部类就是未被 static 修饰的类,例如:
class Out{ public int a; private int b; private static int c; //实例内部类 class In{ public int d; private int e; public void print(){ System.out.println("内部类!"); } } public void show(){ System.out.println("外部类!"); } }1. 如何去实例化一个实例内部类?
记住一句话:先有外部类对象,再有内部类对象。因为实例内部类是在外部类中定义的,所以实例内部类是外部类的一个成员,因此在实例化一个实例内部类之前,要先实例化一个外部类,而实例化对象的类型是 外部类类名 . 内部类类名 ,例如:
public class Test { public static void main(String[] args) { //第一种 Out out = new Out(); Out.In in = out.new In(); //第二种 Out.In in1 = new Out().new In(); } }2. 为什么实例内部类中不能定义一个由 static 修饰的成员,除非是 static final ?
因为静态成员是类本身的属性,是在类加载的时候创建的,而普通成员因依赖于对象,是在实例化对象的时候创建。
因为static final 修饰的是一个常量,它不在类加载时创建,而是在编译时完成,所以可以。
3. 在实例内部类方法中访问同名的成员时,访问谁的?如果要访问外部类同名的成员,如何访问?
遵守就近原则,优先访问实例内部类的成员,如果要访问外部类同名的成员,用 外部类类名.this.来访问,因为实例内部类的非静态方法中包含了一个指向外部类对象的引用。如下:
class Out{ public int a = 5; private int b; private static int c; class In{ public int a = 10; public int d; private int e; static final int f = 10; public void print(){ System.out.println(a);//就近原则,优先访问实例内部类的 System.out.println(Out.this.a);//要访问外部类同名的成员,用 外部类类名.this.来访问 System.out.println("内部类!"); } } public void show(){ System.out.println("外部类!"); } }4. 我们如何在外部类方法中访问内部类的成员?
先创建一个实例内部类对象,再通过对象去访问,例如:
class Out{ public int a = 5; class In{ public int a = 10; public int d = 20; public void print(){ System.out.println("内部类!"); } } public void show(){ In in = new In();//只有在外部类中才可以这样实例化 System.out.println(in.d); System.out.println("外部类!"); } }总结一下:
1. 外部类中的任何成员都可以在实例内部类方法中直接访问
2. 实例内部类可以当成外部类的成员,所以实例内部类也受public,private等访问限定符的限制
3. 创建实力内部类对象必须先创建外部类对象
4. 实例内部类不能定义静态成员(除了static final)
5. 在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须使用 外部类类名.this.同名成员 来访问
6. 外部类中不能直接访问内部类中的成员,若要访问,必须先创建实例内部类的对象
二,静态内部类
静态内部类就是被static修饰的类,例如:
class Out{ public int date1 = 1; private static int date2; public static void print(){ System.out.println("外部类!"); } public void print1(){ System.out.println("1232132"); } //静态内部类 static class In{ public int date3 = 3; private static int date4 = 4; public void test(){ System.out.println("内部类!"); } } }1. 如何实例化一个静态内部类?
与实例内部类不同,因为静态内部类是由static修饰的,说明静态内部类是外部类本身的属性,因此创建静态内部类时要 new 外部类类名.静态内部类类名(); 如下:
public class Test { public static void main(String[] args) { /*Out.In in1 = new Out().new In();错误写法*/ Out.In in = new Out.In();//创建静态内部类 } }2. 静态内部类可以定义由static 修饰的成员(即静态成员)
3. 为什么静态内部类的方法不可以直接访问外部类中的非静态成员?
因为静态内部类是由static修饰,是在类加载时创建的,而非静态成员依赖于对象,是在实例化对象的时候创建,也就是说,我们在静态内部类中访问的外部类非静态成员时,它们还没有被创建,也就无法访问。
那么我们如何间接的访问呢?很简单,在方法中实例化一个外部类对象,通过对象的引用去访问。
class Out{ public int date1 = 1; private static int date2; public static void print(){ System.out.println("外部类!"); } public void print1(){ System.out.println("1232132"); } static class In{ public int date3 = 3; private static int date4 = 4; public void test(){ //实例化外部类对象,通过对象访问非静态 Out out = new Out(); System.out.println(out.date1); out.print1(); //可以直接访问静态的 print(); date2 = 9; System.out.println("内部类!"); } } }与实例内部类的不同点:
1. 静态内部类对象的创建是直接 new 外部类类名.内部类类名() ,不需要先实例化一个外部类对象
2. 静态内部类中的方法不能直接访问外部类中的静态成员,若硬要访问就必须先实例化一个外部类对象
3. 静态内部类可以定义静态成员
三,局部内部类
局部内部类:定义在外部类方法中的类 - 几乎不使用,了解一下
class Out{ public void print(){ class In{ public int date = 10; } In in = new In(); System.out.println(in.date); } }注意:
1. 局部内部类只能在所定义的方法体内部使用
2. 不能被public、static等修饰符修饰
四,匿名内部类
匿名内部类,顾名思义就是没有名字的类,使用起来与上面的都不同,需要与接口一起使用,代码如下:
interface A{ void B(); } public class Test { public static void main(String[] args) { //可以这样理解:有一个类 实现了A接口 并且重写了 B方法 //第一种使用方法 new A(){ @Override public void B() { System.out.println("hhhhhh"); } }.B(); //第二种使用方法 A a = new A() { @Override public void B() { System.out.println("111111"); } }; a.B(); } }这里编译之后,这个匿名内部类实际上变成了 A$1 类!!!
