太自由

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
 1 //79-80-面向对象-内部类-体现
 2 /*
 3 当A类中的内容要被B类直接访问,而A类还需要去创建B类的对象,访问B的内容时,
 4 这时可以将B类定义到A类的内部,这样访问更为便捷。
 5 
 6 将B类称之为内部类(内置类,嵌套类).
 7 
 8 访问方式总结:
 9 内部类可以直接访问外部类中的所有成员,包含私有的。
10 而外部类要想访问内部类中的成员,必须创建内部类对象。
11 
12 当描述事物时,事物的内部还有事物时,而这个内部的事物还在访问外部事物中的内容。
13 这时就将这个事物通过内部类来体现。
14 
15 
16 【内部类被访问的方式】
17 情况一:内部类在成员位置上的被访问方式。
18         成员是可以被指定的修饰符所修饰的。
19         public :不多见,因为更多的时候,内部类已经被封装到了外部类中,不直接
20                         对外提供。
21         static:
22 */
23 
24 class Outer//外部类
25 {
26     private static int num = 4;
27 
28     public class Inner//内部类
29     {
30 //        static final int x = 3;
31         void show()
32         {
33             System.out.println("num="+num);
34         }
35         static void show1(){}//非静态内部类中不允许定义静态成员。仅允许在
36                              //非静态内部类中定义常量。(final)
37                              //如果想要在内部类中定义静态成员,那么内部类也必须
38                              //别静态修饰。
39     }
40 
41     /*
42     内部类被静态修饰后,随着Outer的加载而加载,可以把一个静态内部类理解为就是一个外部类。
43     */
44     static class Inner2
45     {
46         void show2()
47         {
48             System.out.println("Inner2 show2 run..."+num);
49         }
50         static void staticShow()
51         {
52             System.out.println("Inner2 staticShow run");
53         }
54     }
55     void method()
56     {
57         //Outer.Inner in = new Outer.Inner();//这样写也是可以的。
58         Inner in = new Inner();
59         in.show();
60     }
61 }
62 
63 class Inner
64 {
65     public static void main(String[] args)
66     {
67 //        Outer out = new Outer();
68 //        out.method();
69 
70         //测试情况一:直接访问Outer类中的内部类的非静态成员。
71 
72         //创建内部类的对象就可以了,内部类作为成员,应该先有外部类对象,再有内部类对象。
73 //        Outer.Inner in = new Outer().new Inner();
74 //        in.show();
75 
76         //测试二:对静态内部类中的非静态成员进行调用,如何弄?
77         //因为内部类是静态,所以不需要创建Outer的对象,直接创建内部类对象就行了。
78 //        Outer.Inner2 in = new Outer.Inner2();
79 //        in.show2();
80 
81         //如果静态内部类中有静态成员该如何访问呢?既然静态内部类已随外部类加载,而且
82         //静态成员随着类的加载而加载,这时就不需要对象,直接用类名调用即可。
83         Outer.Inner2.staticShow();
84 
85     }
86 }
 1 //81-面向对象内部类访问外部类的原因。
 2 /*
 3 为什么内部类就能直接访问外部类中的成员呢?
 4 那是因为内部类持有了外部类的引用 外部类.this
 5 
 6 对于静态内部类不持有 外部类.this 而是直接使用外部类名。
 7 */
 8 class Outer
 9 {
10     int num = 3;
11     
12     class Inner
13     {
14         int num = 4;
15         void show()
16         {
17             int num = 5;
18             System.out.println("num="+num);
19             System.out.println("num="+this.num);
20             System.out.println("num="+Outer.this.num);
21         }
22     }
23     void method()
24     {
25         //System.out.println(/*Outer.this.*/num);
26         new Inner().show();
27     }
28 }
29 class  InnerClassDemo2
30 {
31     public static void main(String[] args) 
32     {
33         Outer out = new Outer();
34         out.method();
35     }
36 }
 1 /*
 2 内部类其实也可以定义在外部类的局部变量位置上。
 3 
 4 内部类定义在局部时,只能访问被final修饰的局部变量。
 5 为啥呢?因为编译生成的class中直接操作那个最终的数值了。
 6 所以可以访问final,因为其值不会变化。
 7 
 8 为什么不能访问非最终的局部变量呢?
 9 */
10 class Outer
11 {
12     int num = 3;
13 //    Object obj;
14     
15     void method()
16     {
17          int x = 5;//局部变量。省略的final修饰符。
18 //         x = 4;       //编译失败,因为x默认为final的。
19          int y = 3;
20         class Inner//局部内部类。不能被成员修饰符修饰。
21         {
22             void show()
23             {
24                 System.out.println("x="+x);
25                 System.out.println("x="+y);//若y没有加默认的final修饰符,则
26                                             //访问失败,因为y的声明周期太短了。
27                 System.out.println("Inner show run..."+num);
28             }
29         }
30         new Inner.show();
31 //        obj = new Inner();
32     }
33 }
34 
35 class Outer2
36 {
37     Object obj;
38     public void method()
39     {
40         int y = 9;
41         class Inner//extends Object
42         {
43             //覆盖了toString方法
44             public String toString()
45             {
46                 return "tostring"+y;//假设可以访问。
47             }
48         }
49         obj = new Inner();//给obj赋一个Inner对象。
50     }
51     public void function()
52     {
53         System.out.println(obj.toString());
54     }
55 }
56 
57 class  InnerClassDemo5
58 {
59     public static void main(String[] args) 
60     {
61         Outer out  = new Outer();
62         out.method();
63     }
64 }
 1 //83-84内部类-内部类的继承或者实现&匿名内部类。
 2 /*
 3 看API,发现类名或者接口的名称中有 . 说明是内部类,或者内部接口。
 4 
 5 内部了的延伸。
 6 内部类是可以继承或者实现外部其他的类或者接口的。
 7 
 8 好处在于,通过内部类的方式对类进行继承重写,或者接口进行实现。
 9 通过公共的方式对其内部类对象进行访问,因为通常内部类很有可能被外部类封装其中。
10 我们就可以通过接口的方式访问到内部类。
11 
12 
13 对以下代码进行简化。
14 匿名内部类,其实就是一个带有内容的子类对象。
15 格式: new 父类or接口()(子类内容。)
16 
17 匿名内部类就是内部类的简化形式。
18 别忘了,凡是简化的都有局限性。匿名内部类有前提,
19 匿名内部类必须继承父类或者实现接口。
20 */
21 
22 //定义一个抽象的外部类。
23 abstract class AbsDemo
24 {
25     abstract void show();
26 }
27 
28 class Outer
29 {
30     int num = 3;
31     /*
32      class Inner extends AbsDemo
33     {
34         //重写抽象方法show。
35         void show()
36         {
37             System.out.println("num="+num);
38         }
39     }
40     
41     //获取内部类的对象。
42     public AbsDemo getObject()//多态:AbsDemo abs = new Inner();
43     {
44         return new Inner();
45     }
46     */
47     public void method()
48     {
49 //        new Inner().show();
50         /*
51         不想创建具体的子类型,还想创建AbsDemo的子类对象。
52         怎么实现呢?没有子类型,干脆直接使用父类型就可以了。
53         可是在该例子中是抽象类,怎么可以new对象呢?
54         抽象类之所以不能new对象,是因为抽象方法没有被覆盖。只要
55         重写不就可以了吗?
56         */
57         new AbsDemo()//这就是一个AbsDemo的子类对象。只不过这个对象有点胖。
58                     //这是一个带着内容的子类对象。
59                     //这种写法有一个称呼,叫做【匿名内部类】。
60         {
61             //直接就重写抽象的show方法。
62             void show()
63             {
64                 System.out.println("num==="+num);
65             }
66         }.show();
67     }
68 }
69 
70 class InnerClassDemo4
71 {
72     public static void main(String[] args) 
73     {
74         //Outer out = new Outer();
75         //    out.method();
76 
77         //如果Inner对外提供,可以如此获取。
78         //Outer.Inner in = out.getObject();
79         //in.show();
80 
81         //如果Inner被private,可以通过父类型获取。
82         //AbsDemo a = out.getObject();
83         //a.show();
84 
85         Outer out = new Outer();
86         out.method();
87     }
88 }
 1 //86-内部类-匿名内部类的使用。
 2 interface Inter
 3 {
 4     void show1();
 5     void show2();
 6     //方法超过两个,建议不要写成匿名内部类。
 7 }
 8 
 9 class Outer
10 {
11     int num = 4;
12 
13     //在一个类中使用一个接口,可以通过内部类来实现。
14     /*
15     class Inner implements Inter
16     {
17         public void show1(){}
18         public void show2(){}
19     }
20     */
21     public void method()
22     {
23         /*
24         Inner in = new Inner();
25         in.show1();
26         in.show2();
27         */
28 
29         //对其简化,写成匿名内部类的形式。
30         Inter in = new Inner()//多态,父类的引用指向了子类对象。
31         {
32             public void show1(){}
33             public void show2(){}
34         };
35         in.show1();
36         in.show2();
37     }
38 }
39 class  InnerClassDemo5
40 {
41     public static void main(String[] args) 
42     {
43         System.out.println("Hello World!");
44     }
45 }
 1 //87-匿名内部类练习。
 2 interface Inter
 3 {
 4     public void show();
 5 }
 6 
 7 class Outer
 8 {
 9     //代码补足。要求使用匿名内部类。
10     public static Inter method()
11     {
12         //既然在Outer类中使用到了Inter对象,可以使用内部类来完成。
13         //需要子类型,只要简化形式即可,因为接口中就只有一个方法。
14         
15         /*
16         return new Inter()
17         {
18             public void show()
19             {
20                 code...;
21             }
22         };
23         */
24 //        return this.new Inter();
25 //    }
26         
27     //还原成内部类。当静态方法访问内部类时,内部类必须是静态的。
28 /*    static class Inner implements Inter
29     {
30         public void show(){}
31     }
32 */
33     }
34 }
35 
36 //面试题:
37 class Outer2
38 {
39     public void method()
40     {
41         //以下两个对象有区别吗?
42         new Object()//当new Object();时,是创建Object对象,而写成new Object(){}时,创建
43                     //的是Object的子类对象。
44         {
45             public void show(){}
46         }.show();//这个可以编译通过
47 
48         Object obj = new Object()
49         {
50             public void show(){}
51         };
52         obj.show();//编译失败。为啥呢?因为匿名内部类是子类对象,当Object obj指向
53                     //时,就被提升了,而Object类中没有定义show()方法。编译失败。
54 
55     }
56     /*
57         //写一个内部类。
58         class Inner extends Object//有父类,可以简化成匿名内部类。
59         {
60             public void show(){}
61         }
62     */
63 }
64 
65 class InnerClassDemo7
66 {
67     public static void main(String[] args) 
68     {
69         Outer.method().show();
70         /*
71         Outer.method():Outer类中有一个method方法,这个方法时静态的。
72         Outer.method().show():能调用show()的必然是对象。说明method方法运算完应
73                               该放回一个对象,而且能调用Inner中的方法,说明
74                               这个对象类型是Inner的。
75         */
76     }
77 }

 

posted on 2016-03-31 21:03  太自由  阅读(205)  评论(0编辑  收藏  举报