Java的内部类

Java的内部类

  

首先我们来了解一下什么是内部类?

  内部类是指在一个外部类的内部再定义一个类.内部类可以是静态static的,也可用public,default,protected和private修饰。(而外部顶级类即类名和文件名相同的只能使用public和default)

 

为什么要使用内部类?

  比如我们在new一个接口的时候,我们是不是需要new一个实现接口的类,然后要实现接口中的方法,显得很麻烦,如果是使用内部类的话,可以直接在类中直接new一个接口的实现,显得是很方便的,又例如我们要使用某一个对象的中的方法,我们是不是new这个类出来,然后调用这个类的方法,这样做的话,类文件会大量的存在,为了避免这种情况,我们也可以借助内部类来实现.

 

一. java内部类的分类

    1. 成员内部类

    2. 方法内部类

    3. 匿名内部类

 

成员内部类

 1 public class Test {
 2      class A{
 3         public void show(){
 4             System.out.println("这是一个成员内部类");
 5         }
 6     }
 7     
 8     /**
 9      * 在下面方法,构建成员内部类的对象,并调用成员内部类中的方法
10      */
11     public void test(){
12         A a = new A();
13         a.show();
14     }
15     
16     public static void main(String[] args) {
17         new Test().test();
18     }
19 }

成员内部类方式二

 1 public class Test1 {
 2     class A {
 3         public void test(){
 4             System.out.println("A");
 5         }
 6     }
 7     
 8     public static void main(String[] args) {
      

      /**
       * 语法: 外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称() ;
       */

 9         Test1.A ta = new Test1().new A();
10         ta.test();
11     }
12 }

方法内部类

1 public class B {
2     public void show(){
3         System.out.println("这是一个方法的外部类");
4     }
5 }
 1 /**
 2  *     测试方法内部类
 3  *
 4  */
 5 public class Test {
 6     public void test(){
 7         class A extends B {
 8             
 9             public void method(){
10                 System.out.println("方法内部类的方法只在该方法中调用");
11             }    
12 
13         }
14         
15         /**
16          * 定义在方法里的类,称为方法的内部类
17          * 且方法内部类中的方法要在该方法中调用
18          */
19         new A().method();
20         
21         System.out.println("该方法执行完毕");
22     }
23     
24     public static void main(String[] args) {
25         Test t = new Test();
26         t.test();
27     }
28 }


方法内部类要注意的局部变量问题

 1 public class Test1 {
 2     private int a = 10 ;
 3     
 4     public void show(){
 5         System.out.println("这是成员的内部类");
 6     }
 7     
 8     /**
 9      * 方法内部类可以直接调用外部类的成员
10      */
11     public void test(){
12         
13         class A {
14             public void showA(){
15                 System.out.println("a= :"+a);
16                 show() ;
17             }
18         }
19         
20         /**
21          * 方法内部类,只有在方法内部调用才有效
22          */
23         new A().showA();
24     }
25     
26     public void test1(){
27         /**
28          * int c = 10 ;
29          * 局部变量是在栈内存的,方法中的变量是随着方法的调用而创建的,随着方法的调用完毕而销毁
30          */
31         
32         /**
33          * 为什么final什么的变量就可以呢?因为final是发生在编译期间的,这个时候它已经编译好了,
34          * 所以是可以引用的
35          */
36         final int c = 10 ;
37         class B {
38             public void showB(){
39                 System.out.println("c="+c);
40             }
41         }
42         
43         /**
44          * 而new出来的的对象是在堆内存的,但是等方法调用完毕会,有可能这个对象还没有销毁
45          * 但是这个方法已经销毁了,让一个存在的对象要调用一个不存在的变量,显然会报错
46          */
47         B b = new B();
48         b.showB();
49     }
50 }

匿名内部类

  

 匿名内部类就是没有名字的局部内部类,不使用关键字class, extends, implements, 没有构造方法。

    什么情况下需要使用匿名内部类?如果满足下面的一些条件,使用匿名内部类是比较合适的:


      a·只用到类的一个实例。
      b·类在定义后马上用到。
      c·类非常小(SUN推荐是在4行代码以下)
      d·给类命名并不会导致你的代码更容易被理解。


    在使用匿名内部类时,要记住以下几个原则:


      a·匿名内部类不能有构造方法。
      b·匿名内部类不能定义任何静态成员、方法和类。
      c·匿名内部类不能是public,protected,private,static。
      d·只能创建匿名内部类的一个实例。
      e·一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
      f·因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。

1 /**
2  * 定义个接口
3  */
4 public interface TestInterface {
5     public void show();
6 }
1 /**
2  * 
3  * 一个类实现一个接口时,要么实现接口中的方法,要么继续抽象
4  */
5 public abstract class Test implements TestInterface{
6     public void test(){
7         System.out.println("这是抽象类中的方法");
8     }
9 }
1 public class AnonymousTest extends Test{
2     
3     public void show() {
4         System.out.println("实现了接口中的方法");
5     }
6 }

测试没有带名字的匿名内部类和带名字的匿名内部类

public class Demo {
    public static void main(String[] args) {
        AnonymousTest at = new AnonymousTest();
        at.show();
        at.test();
        
        
        /**
         * 创建了一个没有名字内部类,它实现了TestInterface接口
         * 同时还创建了一个没有名字的内部类对象
         */
        new TestInterface(){

            public void show() {
                System.out.println("实现了接口中的方法");
            }
            
        }.show();
        
        /**
         * 创建了一个没有名字内部类,它是一个抽象类
         * 同时还创建了一个没有名字的内部类对象
         */
        new Test(){

            public void show() {
                System.out.println("实现了接口中的方法");
            }
        };
        
        /**
         * 这是一个带名字的内部类,它是一个接口
         * 同时创建了一个内部类对象
         */
        TestInterface tf = new TestInterface(){

            public void show() {
                System.out.println("这是接口中的方法");
            }
            
        };
        
        /**
         * 这是一个带名字的匿名内部类,它是抽象的类
         * 同时还创建了一个带名字的内部类对象
         */
        Test t = new Test(){

            public void show() {
                System.out.println("带名字的匿名内部类");
            }
        };
        
        /**
         * 调用方法
         * 
         * t.show()是匿名内部类中的方法
         * t.test()是Test抽象类中的方法
         */
        t.show();
        t.test();
    }
}

匿名内部类做参数传递

 1 /**
 2  *    匿名内部类做参数
 3  *
 4  */
 5 public class Demo1 {
 6     public static void main(String[] args) {
 7         new Demo1().show(new TestInterface(){
 8 
 9             public void show() {
10                 System.out.println("匿名内部类做参数");
11             }
12             
13         });
14     }
15     
16     public void show(TestInterface tf){
17         tf.show();
18     }
19 }

匿名内部类做返回值

 1 public class Demo2 {
 2     public static void main(String[] args) {
 3         TestInterface tf = new Demo2().test();
 4         System.out.println(tf);
 5         
 6         Test t = new Demo2().test1();
 7         System.out.println(t);
 8     }
 9     
10     /**
11      * TestInterface是一个接口
12      * @return TestInterface
13      */
14     public TestInterface test(){
15         return new TestInterface(){
16 
17             public void show() {
18                 System.out.println("匿名内部类做返回值");
19             }
20             
21         };
22     }
23     
24     /**
25      * Test是一个抽象类
26      * @return Test
27      */
28     public Test test1(){
29         return new Test(){
30 
31             public void show() {
32                 System.out.println("匿名内部类做返回值");
33             }
34             
35         };
36     }
37 }
原文地址:https://www.cnblogs.com/li1010425/p/6071346.html