您的位置:首页 > 职场人生

奋斗黑马程序员----Java内部类讲解

2012-09-24 15:32 281 查看
------- android培训java培训、期待与您交流! ----------




/*
*内部类:将一个类定义在另一个类的里面,里面的那个类就称谓内部类(内置类,嵌套类)
*访问特点:
*	内部类可以直接访问外部类中的成员,包括私有成员
*	而外部类要访问内部类中的成员必须要**建立内部类的对象**,那么怎么建立内部类的对象?
*/

/*
* 内部类的访问规则:
* 	1,内部类可直接访问外部类中的成员,包括私有
* 		之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,《格式:外部类.this.》
* 	2,外部类要访问内部类,必须建立内部类对象
*/
class Outer{
private int x = 3;

//内部类作为成员,可以被private修饰,但是,外部类不能被private修饰
class Inner{	//这就是内部类,一个类里面可以定义多个内部类;如果定义为private 的,则new对象受限
//内部类的好处:可以访问Outer类里面的内容
int x = 4;
void function(){
int x = 6;
System.out.println("Inner:"+x);	//会输出6	  如果没有定义4,6,则会输出3,此时省略了:Outer.this.
System.out.println(this.x);		//输出4
System.out.println(Outer.this.x);	//输出3
}
}
void method(){	//method函数和内部类同属一个类
System.out.println(x);
Inner i = new Inner(); //new一个Iner类型的内部类对象,
i.function();
}
}
public class InnerClassDemo {
public static void main(String[] args){
Outer out = new Outer();
out.method();
//我们能不能直接访问内部类中的成员??
//Inner in = new Inner();	错误,如果多个类中都有Inner类呢?
Outer.Inner in = new Outer().new Inner();	//右边:外部类对象.内部类对象
in.function();
}
}

/**
第二讲:静态内部类
*/

/*
* 内部类的访问规则:
* 	1,内部类可直接访问外部类中的成员,包括私有
* 		之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,《格式:外部类.this.》
* 	2,外部类要访问内部类,必须建立内部类对象
*
* 访问格式:
* 1,当内部类定义在外部类的成员位置上,而且非私有,那么在外部其他类中可以直接建立内部类对象
* 	格式:	外部类名.内部类名 变量名 = 外部类对象.内部类对象;
* 			Outer.Inner in = new Outer().new Inner();
* 2,当内部类在成员位置上,就可以被成员修饰符所修饰:比如:private,将内部类在外部类中进行封装;
* 						 static:内部类就具备了静态的特殊性
* 		当内部类被静态修饰后,只能直接访问外部类中的static成员了,此时出现了访问局限
*
*	思考:
* 	在外部其他类中,如果直接访问static内部类的非静态成员呢??
* 		new Outer1.Inner().function(); (正确)
*		new Outer().Inner().function();(错误:因为,new Outer().Inner()...表示,建立一个含有Inner()方法的Outer对象)
*
* 	在外部其他类中,如果直接访问static内部类的静态成员呢??
* 		Outer1.Inner.function();
*
*  注意:当内部类中定义了静态成员,该内部类必须是静态的,否则报错
*
*  当外部类中的静态方法访问内部类时,内部类也必须是静态的
*
*
*/
class Outer1{
private static int x = 3;

//如果一个**类**中的成员都是静态的,那内部类也可是静态的(??为什么,是不是因为内部类和外部方法(类)存在互相访问?)
/**
应该这样说:如果一个内部类中有静态的成员,那内部类必须是静态的(此规定不包括外部类),否则报错
*/
//内部类作为成员,可以被private修饰,但是,外部类不能被private修饰
static class Inner{
/**
* 静态内部类,其访问的外部内容也必须是静态的,因为静态只能访问静态
*
*
* 问题一:静态内部类中的成员是不是必须都是静态的?不是的,如果该变量或者成员没有被所在内部类中静态访问的话,是可以的!
*/
static int x = 4;
void function(){
//int x = 6;
System.out.println("Inner:"+x);	//会输出6	  如果没有定义4,6,则会输出3,此时省略了:Outer.this.
//System.out.println(this.x);		//输出4
//System.out.println(Outer.this.x);	//输出3
}

}
void method(){
System.out.println(x);
Inner i = new Inner(); //new一个内部类对象
i.function();
}
static class Inner2{
void show(){
System.out.println("inner2 show");
}
}
public static void method1(){	//静态成员访问静态成员,必须ok???
/**
//Inner.function();	//无法直接类名调用function,因为,function非静态,但是可以new一个对象,
* 然后访问非静态的成员
*/
Inner in = new Inner();
in.function();
new Inner2().show();
/**
*注意:如果Inner2类非静态,那么会报错;注意此处:Inner是class,但是为什么要写成Inner2()???,、
*因为这是建立对象的格式
*/
}
}

public class InnerClassDemo2 {
public static void main(String[] args){
//Outer out = new Outer();

//内部静态类的访问:
//new Outer1.Inner().function(); //Inner是static的,可以直接类名调用,但function()是非静态的,所以要new一个

//访问静态内部类的静态成员,很少使用
Outer1.Inner.function();
Outer1.method1();

//我们能不能直接访问内部类中的成员??
//Inner in = new Inner();	错误,如果多个类中都有Inner类呢?
//Outer.Inner in = new Outer().new Inner();	//右边:外部类对象.内部类对象
//in.function();
}
}

/**
第三讲:内部类定义原则
*/
/*
* 内部类的访问规则:
* 	1,内部类可直接访问外部类中的成员,包括私有
* 		之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,《格式:外部类.this.》
* 	2,外部类要访问内部类,必须建立内部类对象
*
* 访问格式:
* 1,当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中可以直接建立内部类对象
* 	格式:	外部类名.内部类名 变量名 = 外部类对象.内部类对象;
* 			Outer.Inner in = new Outer().new Inner();
* 2,当内部类在成员位置上,就可以被成员修饰符所修饰:比如:private,将内部类在外部类中进行封装;
* 					 static:内部类就具备了静态的特殊性
* 		当内部类被静态修饰后,只能直接访问**外部类中的static成员**了,此时出现了访问局限
*
* 	在外部其他类中,如果直接访问static内部类的非静态成员呢??
* 		new一个对象	或者	new Outer1.Inner().function();
*
* 	在外部其他类中,如果直接访问static内部类的静态成员呢??
* 		Outer1.Inner.function();	类名直接调用
*
*  注意:当内部类中定义了静态成员,该内部类必须是静态的,否则报错
*
*  当外部类中的静态方法访问内部类时,内部类也必须是静态的,但其成员不受此限制
*
*/

/**
* 内部类的使用条件:(一般用于程序设计上)
*  当描述事物时,事物的内部还有事物,则该事物用内部类来描述。
*  因为内部事物在使用外部事物的内容。
*
*  class Body{	//人体里有心脏,心脏可以使用各个器官
*  	private class XinZang{
*
*  	}
*  	public void show(){	//提供一个show方法,用来访问XinZang
*  		new XinZang();
*  	}
*  }
*
*/
class Outer1{
private static int x = 3;

/**
*如果一个类中的成员有静态的,那内部类必须是静态的,否则报错(最外层类不受此限制)
*
*问题:主函数类的主函数是静态的,那么他所访问的其他类为什么不是静态的?
*/
//内部类作为成员,可以被private修饰,但是,外部类不能被private修饰
static class Inner{
/**
* 静态内部类,其访问的外部内容必须是静态的,因为静态只能访问静态
*
*
* 问题一:静态内部类中的成员是不是必须都是静态的?应该不是
*/
static int x = 4;
static void function(){
//int x = 6;
System.out.println("Inner:"+x);	//会输出6	  如果没有定义4,6,则会输出3,此时省略了:Outer.this.
//System.out.println(this.x);		//输出4
//System.out.println(Outer.this.x);	//输出3
}
}
//	void method(){
//		System.out.println(x);
//		Inner i = new Inner(); //new一个内部类对象
//		i.function();
//	}
static class Inner2{
void show(){
System.out.println("inner2 show");
}
}
public static void method1(){	//静态成员访问静态成员,必须ok???
//Inner.function();
//当外部类中的静态方法访问内部类时,内部类也必须是静态的
new Inner2().show();	//报错,Inner2非静态,注意此处:Inner是class,但是为什么要写成Inner2()??? 这是new对象的格式
}
}

public class InnerClassDemo2 {
public static void main(String[] args){
//Outer out = new Outer();

//内部静态类的访问:
//new Outer1.Inner().function(); //Inner是static的,可以直接类名调用,但function()是非静态的,所以要new一个

//访问静态内部类的静态成员,很少使用
Outer1.Inner.function();
Outer1.method1();

//我们能不能直接访问内部类中的成员??
//Inner in = new Inner();	错误,如果多个类中都有Inner类呢?不能用这种方式建立对象
//Outer.Inner in = new Outer().new Inner();	//右边:外部类对象.内部类对象
//in.function();
}
}

/**
第四讲:
*/

/*
* 内部类只有定义在外部类成员位置上才被private或static修饰,一般内部类不会被public修饰,为什么?
* static或private只修饰成员,非局部
*
* 1,内部类定义在局部时,不可以被成员修饰符修饰,
* 2,可以直接访问外部类中的成员,因为还持有外部类中的引用
* 但是不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量(即,除非该局部变量被fianl修饰)
*/
class Outer2{
int x = 3;
void method(final int a){	//如果在下面内部类的代码中使用到了此参数,则此参数必须是final修饰
//a++;	//报错:The final local variable a cannot be assigned. It must be blank and not using a compound assignment

/**
* 这是一个局部位置,内部类定义在局部位置上,不能被static修饰,其内部的成员也不能被static修饰,
* 否则,该内部类也要被static修饰,
*/
final int y = 4;	//必须被final修饰,为什么???
class Inner{ //此时Inner是局部,不能被static修饰,static只能修饰成员
//使用静态会报错:Illegal modifier for the local class Inner; only abstract or final is permitted

//static int num = 0;
/*
*使用static修饰num会报错:The field num cannot be declared static;
*/

void function(){	//该方法,也不能被static修饰,否则Inner也为static的,static不能修饰局部的内部类
/*使用静态修饰function,会报错:The method function cannot be declared static;
* static methods can only be declared in a static or top level type
*/
System.out.println(Outer.this.x);	//可以直接访问外部类中的成员,因为还持有外部类中的引用
System.out.println(a);	//如果此处访问到a和y,则二者必须被final修饰,即他们都必须是最终变量,
//如果内部类中没有访问,则无此要求
}
}
/**
非静态,没有对象不会运行
*/
new Inner().function();	//使用内部类,且这个new不能放到Inner上面,因为还没有加载到Inner
}
}

public class InnerClassDemo3 {
public static void main(String[] args){
new Outer2().method(7);
new Outer2().method(9);	//这二者是可以同时运行的,不同的类

/**
思考如下代码:可以运行么?
*/
Outer2 out = new Outer2();
out.method(8);	//method在栈中,执行完毕后,会释放,所以两个method不会报错
out.method(9);
/**
因为a是标准的局部变量,所以上述写法和new两个对象没有区别,如果换成x,则会有所不同
method在栈中,执行完毕后,会释放,所以两个method不会报错
*/
}
}

另外一个文件:IneerClassDemo4.java
/**
* 匿名内部类: 没有名字的内部类
* 1,匿名内部类,其实就是内部类的简写格式
* 2,定义匿名内部类的前提:内部类必须继承一个类或者实现一个接口
*
* 3,匿名内部类的格式:new 父类或者接口(){定义子类的内容},其中()指构造函数,{定义子类的内容 }
*
* 4,其实匿名内部类就是一个匿名子类对象。而且这个对象有点胖。可以理解为带内容的对象。
* 5,匿名对象对方法只能调用一次,一次一个
*
* 写匿名对象:就是为了简化书写,覆盖方法
*
* 一般写匿名内部类,其内部方法不会超过三个,
* 5,匿名内部类中定义的方法最好不要超过三个(不包括三个),因为它就是为了简化而存在的,
*		太复杂了就没有意义了(匿名对象调用方法会方便一些???为什么???)
*/

/**讲解:
各种动物都有心脏,但心脏都不一样,如果要声明某一个动物,那么该动物内部应该有一个心脏
因为,各种动物的心脏是不同的,所以将心脏类抽象为一个单独类,然后在每一个动物的内部去实现它
*/
abstract class AbsDemo
{
abstract void show();
}
class Outer3{
int x = 3;
/*  代码块一:
一个内部类可以直接去继承一个外部类,或者外部其他类
class Inner extends AbsDemo
{
void show()	//继承后,一定要要覆盖方法
{
System.out.println("show:"+x);
}
}*/
public void function()
{
//new Inner().show();  //对应代码块一:中的Inner替换为以下内容

//如果一个匿名对象既想调用重写的方法,又想同时调用自身特有的方法,则,此时只能整两个匿名对象

/**
以下代码对应:new Inner().show();
其中,new AbsDemo(){} 替代了Inner(),因为此时不存在对象引用,所以用父类的名字代替
父类是抽象类,所以子类要重写父类方法,
*/
new AbsDemo()	//匿名内部类,这是一个对象,是AbsDemo的子类对象,而且有点胖;这一部分就是代码块一的简写
{	//开发当中如果玩AWT,这种写法很常见,因为简化简单
int num = 9;
void show(){
System.out.println("num==="+num);
}
void abc(){
System.out.println("haha");
}
}.abc();	//这是可以的

//或者可以这样

AbsDemo d = new AbsDemo()	//父类引用调用子类对象,就是多态
{	//开发当中如果玩AWT,这种写法很常见,因为简化简单
void show(){
System.out.println("x==="+x);
}
void abc(){
System.out.println("haha");
}
};
d.show();

//d.abc(); 父类中没有abc(),这里是多态,编译要看父类
new AbsDemo(){
public void show(){

}
void abc(){
System.out.println("这里是abc方法,另一个内部类");
}
}.abc();	//这样使用abc()是可以的

//匿名对象对方法只能调用一次
new AbsDemo()//匿名内部类,AbsDemo的匿名子类对象,是上面绿色部分的简写方法
{
int num = 9;	//这样定义num可以么??
void show()	//重写方法
{
System.out.println("num==="+num);//这样访问num是可以的,就相当于在一个类中定义了一个num,然后拿来用
}
void abc()
{
System.out.println("haha");
}
};
}
}
public class InnerClassDemo4
{
public static void main(String[] args)
{
new Outer3().function();
}

}

/**练习题:
*InnerClassTest.java,这个文件无法理解!要再次看视频~!
*/

interface Inter{
void method();
}
class Test{
/**
补足代码,通过匿名内部类。
*/

/* 代码块二
*这是一般实现,这是内部类,但非匿名内部类 注意观察
*这段代码有问题,不知怎么理解!!
static class Inner implements Inter
{
public void method(){
System.out.println("method run");
}
}
static Inter function()	//返回值是Inter类型的
{	//和下面的代码块有什么不同么?
return new Inner();	//在该函数中调用内部类Inner
}
*/

//代码块儿二可用如下代码替代
static Inter function()
{ ////This method must return a result of type Inter

/**匿名内部类,没有名字了,用Inter代替Inner
*接口不能跟对象,要覆盖???
*/
/**
* 因为return的是一个Inter对象类型的,所以上面要定义成一个返回Inter类型的函数,
*  不能定义成void或着其他类型的
*/
return new Inter()	//这个就是匿名内部类
{
public void method(){	//覆盖方法
System.out.println("method run");
}
};
}
}
class InnerClassTest {
public static void main(String[] args){
Test.function().method();	//要能看懂这句话
/**
*解读:Test.function():Test类中有一个静态的方法:function(),因为main是static的,只能访问static的(或者说是类名调用,只能是静态的)
*.method():父类中,method()方法是非静态的(抽象的),而function()后面又加了该方法,
*所以function这个方法运算后的结果是一个对象,而且也只有对象才能调用方法,
*而且是一个Inter类型的对象,为什么??因为method方法在Inter里面,只有Inter才能调用method方法
*因为只有是Inter类型的对象,才可以调用method方法
*
*	Inter in = Test.function();  全写
*	in.method();
*	但这么写就暴漏出来了
*/

show	//对应下面代码块三:多多练习
(
new Inter()	//匿名内部类
{	//传入一个接口
public void method(){
System.out.println("method show run");
}
}
);	//show的参数是一个接口,注意末尾的“;”号
}

/**	代码块三:
*匿名内部类的使用环境(什么情况下使用匿名内部类??)
*/
public static void show(Inter in)	//假如,Inter是接口类型,查看Inter后发现,Inter只有不超过三个方法时(2个或1个)
{	//Inter in 是一个接口类型,使用时,要传入一个接口
in.method();
}
}

/**小面试题:
*如果:没有父类,没有接口,还能写匿名内部类么?就想搞一个方法运行一下,function方法
*/
class InnerTest{
/*在这题中没有这块代码
static class Inner
{
void function()
{

}
}
*/
public static void main(String[] args){
//new Inner.function();	//因为没有上面的代码块,所以不能这么使用,换成下面的Object子类对象
//new Object();	//创建一个Object对象
new Object()  //Object的子类对象,此处不建议建立一个引用
{	//此时,不能用   Object o = new Object(){}	因为父类Object没有function方法,下面不能使用o.function();
public void function(){

}
}.function();
}
}

[b]---------- [/b]android培训java培训、期待与您交流!---------- 
 详细请查看:http://edu.csdn.net/heima/




                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: