内部类

概念

 内部类

    内部类访问规则

    1.内部类可以直接访问外部类中的成员,包括私有[例1]

       之所以可以直接访问外部类成员,是因为内部类中持有了一个外部类的引用,格式是 外部类名.this[例3]

      2.外部类要访问内部类,必须建立内部类对象[两种写法][例2]

      第二种写法格式

      当内部类定义在外部类成员位置上,而且非私有,可以在外部其他类中,直接创建内部类对象

      外部类名.内部类名  变量名 =外部类对象.内部类对象

      Outer.  Inner  in=new Outer().new Inner();

      3.当内部类在成员位置,就可以被外部类修饰符所修饰

       比如:private 将内部类在外部类中进行封装

      4.静态内部类(static)

       当内部类被static修饰后,内部类就具备了static特性,只能直接访问外部类中的static成员,也就是说出现了访问局限 

     误区

      在外部其他类中,如何访问static内部类中的非static成员[例4]

      外部类对象.内部类名().内部类非staic方法名()

      new InnerDemo.ClassDemo().Demo();

      在外部其他类中,如何访问static内部类中的static成员[例5]

      外部类名.内部类名().内部类static方法();

      InnerDemo.ClassDemo.Demo();

      注意  

      当内部类中定义了静态成员,该内部类必须是静态的[例6]

      当外部类中的静态方法访问内部类时,内部类必须是静态的[例7]

      什么时候使用内部类?

     当描述事物时,事物的内部还有事物,该事物用内部类来描述,因为内部事物在使用外部事物的内容  

       5.内部类定义在局部时[定义在外部类的方法中]

     注意:内部类可以定义在外部类的任意位置,分为成员位置和局部位置,所以局部不单单指定义在方法中

       (1)可以直接访问外部类的成员,因为还持有外部类的引用,但是不可以访问它所在的局部中的变量,只能访问被final修饰的局部中的变量[常量][例8]

          典型特殊案例[例9]

  匿名内部类 

      1.匿名内部类其实就是内部类的简写格式[例10]

      2.定义匿名内部类的前提[例10]

       内部类必须是继承一个类或者实现接口

       3.匿名内部类的格式[例10]

        new 父类或者接口() {定义子类的内容}

       4.其实匿名内部类就是一个匿名子类对象,而且这个对象有点"胖",可以理解为没有名字带内容的对象[例10]

      匿名内部类一次只能调用一个方法[例11]

       5.匿名内部类中定义的房啊最好不要超过3个[不包括3个]  

      什么时候使用匿名内部类? 

       一个类继承一个接口,并且这个接口只有不到3个方法  

示例代码

例1

 1 import java.lang.reflect.Method;
 2 
 3 import com.preview.seven.InnerDemo.ClassDemo;
 4 
 5 public class InnerClass {
 6     public static void main(String[] args) {
 7 
 8     }
 9 }
10 
11 class InnerDemo {
12     private int num = 3;
13 
14     class ClassDemo {
15         public void Demo() {
16             System.out.println("我是内部类的方法" + " " + num); //可以直接父类中的num,不会报错
17         }
18     }
19 
20     public void inner2() {
21         System.out.println("我是外部类的方法");
22     }
23 }

例2

第一种写法

 1 import java.lang.reflect.Method;
 2 
 3 import com.preview.seven.InnerDemo.ClassDemo;
 4 
 5 public class InnerClass {
 6     public static void main(String[] args) {
 7         InnerDemo innerDemo=new InnerDemo();
 8         innerDemo.inner2();
 9     }
10 }
11 
12 class InnerDemo {
13     private int num = 3;
14 
15     class ClassDemo {
16         public void Demo() {
17             System.out.println("我是内部类的方法" + " " + num); //我是内部类的方法 3
18         }
19     }
20 
21     public void inner2() {
22         System.out.println("我是外部类的方法");  //我是外部类的方法
23         ClassDemo classDemo=new ClassDemo();
24         classDemo.Demo();
25     }
26 }

第二种写法

 1 import java.lang.reflect.Method;
 2 
 3 import com.preview.seven.InnerDemo.ClassDemo;
 4 
 5 public class InnerClass {
 6     public static void main(String[] args) {
 7         InnerDemo.ClassDemo classDemo=new InnerDemo().new ClassDemo();
 8         classDemo.Demo();
 9     }
10 }
11 
12 class InnerDemo {
13     private int num = 3;
14 
15     class ClassDemo {
16         public void Demo() {
17             System.out.println("我是内部类的方法" + " " + num); // 我是内部类的方法 3
18         }
19     }
20 
21     public void inner2() {
22         System.out.println("我是外部类的方法");
23 
24     }
25 }

 1 import java.lang.reflect.Method;
 2 
 3 import com.preview.seven.InnerDemo.ClassDemo;
 4 
 5 public class InnerClass {
 6     public static void main(String[] args) {
 7         InnerDemo.ClassDemo classDemo = new InnerDemo().new ClassDemo();
 8         classDemo.Demo();
 9     }
10 }
11 
12 class InnerDemo {
13     private int num = 3;
14 
15     class ClassDemo {
16         private int num=4;
17         
18         public void Demo() {
19             System.out.println("我是内部类的方法" + " " + num); // 我是内部类的方法 4
20             System.out.println("我是内部类的方法" + " " + InnerDemo.this.num); // 我是内部类的方法 3
21         }
22     }
23 
24     public void inner2() {
25         System.out.println("我是外部类的方法");
26 
27     }
28 }

例4

 1 import java.lang.reflect.Method;
 2 
 3 import com.preview.seven.InnerDemo.ClassDemo;
 4 
 5 public class InnerClass {
 6     public static void main(String[] args) {
 7 
 8         new InnerDemo.ClassDemo().Demo();
 9     }
10 }
11 
12 class InnerDemo {
13     private static int num = 3;
14 
15     static class ClassDemo {
16 
17         public void Demo() {
18             System.out.println("我是内部类的方法" + " " + num); // 我是内部类的方法 3
19         }
20     }
21 
22     public void inner2() {
23         System.out.println("我是外部类的方法");
24 
25     }
26 }

例5

 1 public class InnerClass {
 2     public static void main(String[] args) {
 3         InnerDemo.ClassDemo.Demo();
 4     }
 5 }
 6 
 7 class InnerDemo {
 8     private static int num = 3;
 9 
10     static class ClassDemo {
11 
12         public static void Demo() {
13             System.out.println("我是内部类的方法" + " " + num); // 我是内部类的方法 3
14         }
15     }
16 
17     public void inner2() {
18         System.out.println("我是外部类的方法");
19 
20     }
21 }

例6

 1 import java.lang.reflect.Method;
 2 
 3 import com.preview.seven.InnerDemo.ClassDemo;
 4 
 5 public class InnerClass {
 6     public static void main(String[] args) {
 7         InnerDemo.ClassDemo.Demo();
 8     }
 9 }
10 
11 class InnerDemo {
12     private static int num = 3;
13 
14     class ClassDemo {
15 
16         public static void Demo() {
17             System.out.println("我是内部类的方法" + " " + num); // 我是内部类的方法 3
18         }
19     }
20 
21     public void inner2() {
22         System.out.println("我是外部类的方法");
23 
24     }
25 }

视图

例7

 1 import java.lang.reflect.Method;
 2 
 3 import com.preview.seven.InnerDemo.ClassDemo;
 4 
 5 public class InnerClass {
 6     public static void main(String[] args) {
 7         InnerDemo innerDemo=new InnerDemo();
 8         innerDemo.inner2();
 9     }
10 }
11 
12 class InnerDemo {
13     private static int num = 3;
14 
15     class ClassDemo {
16 
17         public void Demo() {
18             System.out.println("我是内部类的方法" + " " + num); // 我是内部类的方法 3
19         }
20     }
21 
22     public static void inner2() {
23         new ClassDemo().Demo();
24         
25     }
26 }

视图

 

例8 

 1 import java.lang.reflect.Method;
 2 
 3 public class InnerClass {
 4     public static void main(String[] args) {
 5         InnerDemo innerDemo = new InnerDemo();
 6         innerDemo.method();
 7 
 8     }
 9 }
10 
11 class InnerDemo {
12     private int x = 3;
13 
14     public void method() {
15         int y = 10;
16 
17         class Demo {
18 
19             void methodDemo() {
20                 System.out.println("我是局部内部类中的方法" + " " + y); // 我是局部内部类中的方法 3
21 
22             }
23         }
24 
25         new Demo().methodDemo();
26     }
27 
28 }

视图

例9

 情况一,不会出错

 1 import java.lang.reflect.Method;
 2 
 3 public class InnerClass {
 4     public static void main(String[] args) {
 5         InnerDemo innerDemo = new InnerDemo();
 6         innerDemo.method(10);
 7         innerDemo.method(75);
 8 
 9     }
10 }
11 
12 class InnerDemo {
13     private int x = 3;
14 
15     public void method(final int a) {
16         final int y = 10;
17 
18         class Demo {
19 
20             void methodDemo() {
21                 System.out.println("我是局部内部类中的方法" + " " + a); // 我是局部内部类中的方法 10
22                                                                 // 我是局部内部类中的方法75
23                                                                  
24 
25             }
26         }
27 
28         new Demo().methodDemo();
29     }
30 
31 }

解析

  在这个代码中,虽然final定义的内容只能初始化一次,并且无法修改,但是当第一次调用method方法时,系统会在栈内存中创建一个final a,但是当第一个method调用完成后,这个栈中的a就会销毁,当第二次调用method方法时,系统会在栈内存重新定义一个final a,所以两次调用method方法所使用的a不是同一个,所以调用两次都会输出不同的结果

视图

情况二,会出错

 

 1 import java.lang.reflect.Method;
 2 
 3 public class InnerClass {
 4     public static void main(String[] args) {
 5         InnerDemo innerDemo = new InnerDemo();
 6         innerDemo.method(10);
 7         innerDemo.method(75);
 8 
 9     }
10 }
11 
12 class InnerDemo {
13     private int x = 3;
14 
15     public void method(final int a) {
16 
17         a++;
18         final int y = 10;
19         class Demo {
20 
21             void methodDemo() {
22                 System.out.println("我是局部内部类中的方法" + " " + a);
23 
24             }
25         }
26 
27         new Demo().methodDemo();
28     }
29 
30 }

 

视图

例10

原代码

 1 import java.lang.reflect.Method;
 2 
 3 public class InnerClass {
 4     public static void main(String[] args) {
 5         InnerDemo innerDemo=new InnerDemo();
 6         innerDemo.test01();
 7     }
 8 }
 9 
10 abstract class AbsDemo {
11     abstract void show();
12 }
13 
14 class InnerDemo {
15     int a = 0;
16 
17     class Demo01 extends AbsDemo {
18         void show() {
19             System.out.println("我是改写为匿名内部类之前的代码"+" "+a); //我是改写为匿名内部类之前的代码 0
20 
21         }
22     }
23 
24     void test01(){
25         new Demo01().show();
26     }
27 }

改为内部类代码

 1 import java.lang.reflect.Method;
 2 
 3 public class InnerClass {
 4     public static void main(String[] args) {
 5         InnerDemo innerDemo = new InnerDemo();
 6         innerDemo.test01();
 7     }
 8 }
 9 
10 abstract class AbsDemo {
11     abstract void show();
12 }
13 
14 class InnerDemo {
15     int a = 0;
16 
17     void test01() {
18         new AbsDemo() {
19             void show() {
20                 System.out.println("我是改写为匿名内部类之后的代码" + " " + a); //我是改写为匿名内部类之后的代码 0
21 
22             }
23         }.show();
24     }
25 
26 }

例11

匿名内部类一次只能调用一个方法

 1 import java.lang.reflect.Method;
 2 
 3 public class InnerClass {
 4     public static void main(String[] args) {
 5         InnerDemo innerDemo = new InnerDemo();
 6         innerDemo.test01();
 7     }
 8 }
 9 
10 abstract class AbsDemo {
11     abstract void show();
12 }
13 
14 class InnerDemo {
15     int a = 0;
16 
17     void test01() {
18         new AbsDemo() {
19             void show() {
20                 System.out.println("我是改写为匿名内部类之后的代码" + " " + a); // 我是改写为匿名内部类之后的代码
21                                                                     // 0
22 
23             }
24 
25             void asd() {
26                 System.out.println("我是内部类自己的方法" + a);
27             }
28 
29         }.asd(); // 我是内部类自己的方法0
30         
31         
32         new AbsDemo() {
33             void show() {
34                 System.out.println("我是改写为匿名内部类之后的代码" + " " + a); // 我是改写为匿名内部类之后的代码 0
35                                                                     
36 
37             }
38 
39             void asd() {
40                 System.out.println("我是内部类自己的方法" + a);
41             }
42 
43         }.show(); //我是改写为匿名内部类之后的代码 0
44 
45     }
46 
47 }
posted @ 2016-08-18 21:03  IT蓄水池  阅读(138)  评论(0)    收藏  举报