内部类总结

内部类:定义在一个类的内部的类就是内部类,也叫内置类,内嵌类
1、内部类访问外部类:
在内部类中可以直接访问外部类中的非静态成员,即不用创建外部类的对象,就可以直接访问外部类的非静态成员。
原因是:内部类成员方法在访问外部类中的非静态成员时省略了Outer.this,本质上还是先拿到外部类的对象
才访问外部类的非静态成员的。不用程序员在内部类中显示的引用外部类的对象,在创建内部类的对象时必须先创
建外部类的成员,所以内部类方法会现在本方法内查找,再在本类中查找,最后到外部类中查找,并通过Outer.this
拿到外部类对象,继而引用外部类的非静态成员。
必须用 Outer.this 和 this 以示区分外部类对象和内部类对象。

2、外部类访问内部类:
外部类访问内部类必须创建内部类的对象,通过内部类的对象才能访问内部类中的非静态成员。

3、一个类中可以定义多个内部类

4、内部类的定义和普通其他类一样,也可以定义成员方法和成员变量

5、只有内部类可以被私有化(即被private修饰,只供在外部类中使用),外部类不可以被私有化,否则编译报错。
外部类只能有两种修饰,默认和public,private只修饰成员,而内部类处在成员的位置上,所以可以被修饰。
内部类处在成员位置上,所以所有成员修饰符都可以用来修饰内部类。
比如:static、private
static修饰的内部类中的成员可以使静态的也可以是非静态的。
****
先明确static关键字的本质含义:静态的一个本质含义:
static修饰代码段时,用来标识出该段代码段中的内容不同于其他非静态代码段。当其需要访问static修饰的
代码段外部的内容时,则该内容必须保证为静态(无论是代码段还是成员变量)。但是在代码段内部仍然可以
创建局部变量,使用其他的类都没有问题。相当于static对外有要求,对内没有要求。比如Outer.this会被
看做成外部的,所以其代表的是外部的非静态变量,所以编译会报错,而内部类的this是内部的,所以其代表
的是内部的非静态变量,相当于代码段内的局部变量,所以是可以非静态的,编译会通过。

根据1,内部类是非静态时,当创建内部类的对象时必须通过外部类的对象,这样做是因为内部类的成员中可以
直接访问外部类中的非静态成员。然而当内部类为静态时,就切断了这层联系,即内部类定义这个大括号(代码
段中)中若要访问外部类的成员,则必须是访问静态的成员,而访问外部类中的静态成员可以不用外部类的
对象,所以就打破了这层联系,所以不需通过外部类对象,所以创建静态内部类对象时,不用先创建外部类
对象,即不用通过创建外部类对象来创建静态内部类的对象。

当在外部类的静态方法中创建非静态内部类的对象时,编译会报错,因为静态方法的访问不需要创建外部类
对象,而非静态的内部类的对象有可能引用到外部类中的非静态成员,而在静态方法中是不会有外
部类对象的(即this),而内部类对象的创建必须通过外部类对象即this。所以就会出错。
而当把内部类声明为静态的时候,就可以在外部类的静态方法中创建内部类的对象了,因为创建静态内部类
不需要用到外部类对象(即this),所以就是完全正确的了。而在外部类中的非静态方法中创建非静态的
内部类对象时,虽然没有明确用new Outer().new Inner()的方式,即没有显示使用外部类对象创建非静态
内部类对象,但实际上还是用到了,是使用this,即相当于this.new Inner()。

静态的另一个本质含义:访问方式的特殊性,可以用类名.静态成员的方式访问。

****
1# 外部其他类中访问静态内部类中的非静态成员变量。
在其他外部类中直接创建静态内部类对象
Outer.Inner in = new Outer.Inner();
因为内部类Inner是静态的,不会用到外部类Outer中的非静态成员,所以不用创建一个匿名的外部类Outer
对象。直接创建一个内部类对象就可以了。
在外部类中直接创建静态内部类对象
Inner in = new Inner();
2# 外部其他类中访问静态内部类中的静态成员
访问方式:外部类类名.内部类类名.静态成员
Outer.Inner.function();



6、成员访问上,内部类和外部类相当于两个命名空间,内部的可以直接引用外部的。在其他类中要声明内部类的引用,
就需要用完全限定名称访问即“外部类名.内部类名”,而在外部类中使用内部类时就只需要用“内部类名”就可以了。
所以不管是创建静态内部类还是非静态内部类都必须用“外部类名.内部类名”来标志内部类名,当在其他外部类使用
该内部类时,因为可能外部类Outer1,Outer2中都有一个Inner的内部类,单纯的靠内部类Inner的名称,编译器无法
确定是要使用哪一个内部类。

7、其他外部类访问非静态内部类,若内部类没有被私有化,则可以通过直接创建内部类对象来访问非静态成员。
访问方式: 外部类名.内部类名 变量名 = 外部类对象.内部类对象
Outer.Inner in = new Outer().new Inner();
注意:这种访问方式,即创建内部类对象的方式不可以用于创建静态内部类对象,否则编译报错
eg. Outer.Inner4 in4 = new Outer().new Inner4();//Inner4是静态内部类。
必须用:Outer.Inner4 in4 = new Outer.Inner4();//这是正确的创建静态内部类的方式。


注意:内部类中如果有静态的方法,则内部类也要被static修饰
外部类中的静态方法中访问到内部类,则内部类也要被static修饰。

注:以上讲的内部类只是成员内部类,即内部类定义在外部类的成员位置上。

测试代码:

class Outer
{
	static int x = 3;

	Outer()
	{
	}
	Outer(int x)
	{
		this.x = x;
	}
	static class Inner
	{
//		int x = 4;
		static void function()
		{
//			int x = 5;
//			System.out.println("Inner :"+x);	//5
//			System.out.println("Inner :"+this.x);	//4
			System.out.println("Inner :"+x);	//3
		}
	}
	static class Inner2
	{
		void function()
		{
			System.out.println("Inner2	:");
			Inner in = new Inner();
			in.function();
//			method();
		}
	}
	class Inner3
	{
		void function()
		{
			System.out.println("Inner3	:"+x);//3
		}
	}
	void method()
	{
//		System.out.println(x);
//		Inner in = new Inner();
//		in.function();
		Inner3 in3 = this.new Inner3();
		in3.function();
	}
	public static void show()
	{
//		Inner.function();
		Inner2 in2 = new Inner2();
		in2.function();
	}
}

  

posted @ 2015-04-18 19:09  蓝色T-shirt  阅读(174)  评论(0编辑  收藏  举报