• 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 }
  • 相关阅读:
    富文本,NSAttributedString,当需要改变的内容有相同的时候的解决方法
    iOS 如何将证书和描述文件给其他人进行真机调试(Provisioning profile "描述文件的名字" doesn't include the currently selected device "你的手机名字".)
    iOS 去除字符串中的H5标签
    The dependency `AMapSearch (~> 3.0.0)` is not used in any concrete target. cocoapods在update或者install的时候报错解决办法
    iOS 3D Touch 五个快捷键的问题
    根据内容计算cell的高度
    iOS UIPickerView 可能会出现选中行不显示或者去掉上下两条横线的问题解决,
    iOS 开发 常用的正则验证表达式:电话 、邮箱等等
    使用MLeaksFinder检测项目中的内存泄露
    iOS 当请求到的数据是double类型,会失去精准度,并且去掉小数点后的0
  • 原文地址:https://www.cnblogs.com/li1010425/p/6071346.html
Copyright © 2020-2023  润新知