奋斗黑马程序员----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/
相关文章推荐
- 奋斗黑马程序员----Java之多线程讲解(一)
- 奋斗黑马程序员----Java GUI基础讲解
- 奋斗黑马程序员----Java之多线程讲解(二)
- 黑马程序员--java高新技术--反射的深入讲解
- 黑马程序员_苏坤老师讲解的数组与自己的练习
- 黑马程序员-java内部类
- 黑马程序员-讲解Vector的特有取出方式Enumeration学习日记
- 黑马程序员--Java内部类的使用小结
- 奋斗黑马程序员----Java之装饰模式小结
- 黑马程序员——基础学习---main方法讲解
- 黑马程序员--java内部类!
- 奋斗黑马程序员----Java之字节流小结
- 黑马程序员 java高新技术<二>--java5的枚举、反射的深入讲解
- 黑马程序员-------Java内部类的使用
- 黑马程序员-java基础加强-反射的深入讲解
- 黑马程序员-c#基础加强版之方法控制流复习-1关于方法的讲解
- 黑马程序员_java内部类
- 黑马程序员—IOS基础之OC—static、self、NSString和NSLog讲解
- 奋斗黑马程序员----Java之File对象小结
- 奋斗黑马程序员----Java异常(Exception)介绍