三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

JAVA-SE-内部类

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 类!!!

← 返回列表