问:简述一下内部类的实质是什么?

书上看到的一个问题,整理下来


简述一下内部类的实质是什么?

内部类是Java的类的一种形式,它的使用语法比較奇怪


分析:

package abc;
class A {//定义外部类A
   class B {//定义内部类B
      ...
   }
}

对于B类来说,它的完整类名就是abc.A.B,命名空间进一步缩小了,而且B对A产生了一种依赖关系,仅仅有A存在的时候B才存在。

依据内部类定义结构的不同, 能够把内部类分为两种:成员式和局部式。成员式内部类指的是它们定义的地方与成员变量和成员方法类似,就好像一个类的成员一样。局部式内部类则是定义在方法体中,仅属于局部范围全部。

然后成员式内部类又分为:静态内部类和成员内部类。

局部式又能够分为:普通局部内部类和匿名内部类。


1、静态内部类

package abc;
class Outter {//定义外部类Outter
	static class Inner {//定义静态内部类Inner
		...
	}
}

在外部类载入的时候,静态内部类也随之载入,它的完整类名是abc.Outter.Inner。编译后的class文件名称为“Outer$Inner.class”。因为静态内部类是静态的。所以它无法訪问外部类的非静态成员。事实上。静态内部类相对于外部类来说,差点儿是独立的,它能够在没有外部类对象的情况下,单独创造一个内部类的对象。

(某种程度上来说,公开的静态内部类就相当于一个普通的类)

总结一下,静态内部类相对于外部类来说。不过包括关系。缩小了命名空间,完整的类名中多了一个外部类的名称。

本质上是独立的两个类。JVM也不知道他们两个有包括关系。


2、成员内部类

没有使用static修饰的内部类,比如以下的代码:

package abc;
class Outter {//定义外部类Outter
	class Inner {//定义成员内部类Inner
		...
	}
}

此时的内部类须要等外部类创建了对象以后才会被载入到JVM中,它属于外部类的某个实例,因此它能够訪问外部类的静态和非静态成员。

创建成员内部类的时候,语法比較特殊。首先创建一个外部类的实例,然后用这个实例调用new语句,代码例如以下:

public static void main(String[] args) {
		Outter o = new Outter();//创建外部类实例
		Outter.Inner i = o.new Inner();//创建内部类实例
	}
对于成员内部类的构造方法来说,系统会自己主动为他加上一个外部类的參数以及一个外部类的成员变量。这是为了遵循先有外部类实例才干有内部类实例的原则,代码例如以下:

class Inner(Outter o){//成员内部类的本质构造方法
		this.o = o;
	}
当内部类訪问外部类的成员时,则是通过该自己主动加入的成员变量进行訪问,就好像以下的代码

o.abc();


3、局部内部类

局部内部类就没有范围的概念了,它仅在定义它的方法中有效,比如以下的代码:

public void adc(){ //成员方法
		class MyLocal{  //定义局部内部类
			...			//局部内部类体
		}
	}
本质上来说,局部内部类它也是以独立的类。仅仅只是它的一些使用受到了限制,比如,它不能使用statickeyword。仅仅能使用final、abstractkeyword。仅能够訪问外部类带有finalkeyword的局部变量,由于它訪问的是一个字面量或镜像,该局部变量已经不存在了。可是。它能够随意的訪问外部类对象的成员变量。

说明:与成员内部类类似,局部内部类的构造方法也会自己主动加上一个外部类型的參数,以及为该内部类加一个外部类型的成员变量。

当局部内部类定义在静态方法中时就相当于静态内部类:当定义在普通的成员方法中时,则相当于成员内部类。


4、匿名内部类

假设一个局部内部类没有名字,则它就是匿名内部类,比如以下的代码:

public void adc(){ //成员方法
		new OneInterface(){  //直接new一个接口
			public void interMethod(){//接口方法
				...
			}
		};
	}
在以上代码中,匿名内部类的定义和使用根本没有出现classkeyword。但其实它还是创建了。

该类实现了OneInterface接口,直接在方法体中就提供详细的实现。假设须要提供构造方法的參数,则直接在OneInterface后边的那个括号里提供就可以,显得很的灵活。其实,它的工作原理相当于局部内部类,仅仅是没有一个详细的名字而已,外部也无法直接使用它。

注意:匿名内部类编译后的class文件的命名是依照匿名内部类的排列顺序来进行的,直接在外部类后面加上“$”和序号,比如Outter$1.class。


【答案】

内部类依据定义的情况能够分为下面4种。

(1)静态内部类:它相当于外部类的静态成员一样,使用static修饰的内部类,它隶属于外部类,使用起来相当于一个独立的外部类。

(2)成员内部类:它相当于外部类普通的成员一样,隶属于外部类的详细对象。在定义它的时候,须要先创建外部类对象。再创建它的实例。

(3)局部内部类:它定义在一个方法的方法体中,它往往仅作为方法短暂的使用,仅仅能訪问用final修饰的局部变量。

(4)匿名内部类:它也定义在方法体中,可是没有一个详细的名字。具有很大的灵活性。工作本质与局部内部类类似。




posted on 2017-06-07 10:21  slgkaifa  阅读(333)  评论(0编辑  收藏  举报

导航