• 内部类(转)


      内部类(Inner class)

             将相关的类组织在一起,从而降低了命名空间的混乱。

              一个内部类可以定义在另一个类里,也可以定义在函数里,甚至可以作为一个表达式的一部分。

              内部类中不能定义静态成员。(静态成员不是对象的特征,只是为了找一个容身之所,所以需要放到一个类中而已,无需放到内部类中)

              java中的内部类分为四种:

                静态内部类static inner class(static nested class)

               成员内部类member inner class

               局部内部类local  inner  class

               匿名内部类 anonymous inner class

        静态内部类static inner class

             最简单的内部类形式。

             定义时加上static关键字

             不能和外部类有相同的名字

             被编译成一个完全独立的 .class文件,名称为OuterClass$InnerClass.class的形式。

             只可以访问外部类的静态成员和静态方法,包括私有静态成员和方法。

             生成静态内部类对象的方式为:

             OuterClass.InnerClass inner=new OuterClass.InnerClass();

     1 静态内部类使用测试
     2 
     3 package com.learnjava.innerclass;
     4 
     5 class StaticInner
     6 {
     7     private static int a = 4;
     8 
     9     // 静态内部类
    10     public static class Inner
    11     {
    12         public void test()
    13         {
    14             // 静态内部类可以访问外部类的静态成员
    15             // 并且它只能访问静态的
    16             System.out.println(a);
    17         }
    18 
    19     }
    20 }
    21 
    22 public class StaticInnerClassTest
    23 {
    24 
    25     public static void main(String[] args)
    26     {
    27         StaticInner.Inner inner = new StaticInner.Inner();
    28         inner.test();
    29     }
    30 }

        成员内部类member inner class

             成员内部类也是定义在另一个类中,但是定义时不用static修饰。

             成员内部类和静态内部类可以类比为非静态的成员变量和静态的成员变量。

             成员内部类就像一个实例变量。

             它可以访问它的外部类的所有成员变量和方法,不管是静态的还是非静态的都可以。

             在外部类里面创建成员内部类的实例:

             this.new  InnerClass();

             在外部类之外创建内部类的实例:

             (new OuterClass()).new  InnerClass();

             在内部类里访问外部类的成员:

             OuterClass.this.member

     1 成员内部类使用测试
     2 
     3 package com.learnjava.innerclass;
     4 
     5 class MemberInner
     6 {
     7     private int d = 1;
     8     private int a = 2;
     9 
    10     // 定义一个成员内部类
    11     public class Inner2
    12     {
    13         private int a = 8;
    14 
    15         public void doSomething()
    16         {
    17             // 直接访问外部类对象
    18             System.out.println(d);
    19             System.out.println(a);// 直接访问a,则访问的是内部类里的a
    20 
    21             // 如何访问到外部类里的a呢?
    22             System.out.println(MemberInner.this.a);
    23         }
    24 
    25     }
    26 
    27 }
    28 
    29 public class MemberInnerClassTest
    30 {
    31 
    32     public static void main(String[] args)
    33     {
    34 
    35         // 创建成员内部类的对象
    36         // 需要先创建外部类的实例
    37         MemberInner.Inner2 inner = new MemberInner().new Inner2();
    38 
    39         inner.doSomething();
    40     }
    41 }

        局部内部类Local  Inner  Class

             局部内部类定义在方法中,比方法的范围还小。是内部类中最少用到的一种类型。

             像局部变量一样,不能被public,protected,private和static修饰。

             只能访问方法定义中的final类型的局部变量。

             局部内部类在方法中定义,所以只能在方法中使用,即只能在方法当中生成局部内部类的实例并且调用其方法。

     1 局部内部类使用测试
     2 
     3 package com.learnjava.innerclass;
     4 
     5 class LocalInner
     6 {
     7     int a = 1;
     8 
     9     public void doSomething()
    10     {
    11         int b = 2;
    12         final int c = 3;
    13         // 定义一个局部内部类
    14         class Inner3
    15         {
    16             public void test()
    17             {
    18                 System.out.println("Hello World");
    19                 System.out.println(a);
    20 
    21                 // 不可以访问非final的局部变量
    22                 // error: Cannot refer to a non-final variable b inside an inner
    23                 // class defined in a different method
    24                 // System.out.println(b);
    25 
    26                 // 可以访问final变量
    27                 System.out.println(c);
    28             }
    29         }
    30 
    31         // 创建局部内部类的实例并调用方法
    32         new Inner3().test();
    33     }
    34 }
    35 
    36 public class LocalInnerClassTest
    37 {
    38     public static void main(String[] args)
    39     {
    40         // 创建外部类对象
    41         LocalInner inner = new LocalInner();
    42         // 调用外部类的方法
    43         inner.doSomething();
    44     }
    45 
    46 }

        匿名内部类Anonymous Inner Class

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

             匿名内部类隐式地继承了一个父类或者实现了一个接口。

             匿名内部类使用的比较多,通常是作为一个方法参数。

     1 匿名内部类使用测试
     2 
     3 package com.learnjava.innerclass;
     4 
     5 import java.util.Date;
     6 
     7 public class AnonymouseInnerClass
     8 {
     9 
    10     @SuppressWarnings("deprecation")
    11     public String getDate(Date date)
    12     {
    13         return date.toLocaleString();
    14 
    15     }
    16 
    17     public static void main(String[] args)
    18     {
    19         AnonymouseInnerClass test = new AnonymouseInnerClass();
    20 
    21         // 打印日期:
    22         String str = test.getDate(new Date());
    23         System.out.println(str);
    24         System.out.println("----------------");
    25 
    26         // 使用匿名内部类
    27         String str2 = test.getDate(new Date()
    28         {
    29         });// 使用了花括号,但是不填入内容,执行结果和上面的完全一致
    30             // 生成了一个继承了Date类的子类的对象
    31         System.out.println(str2);
    32         System.out.println("----------------");
    33 
    34         // 使用匿名内部类,并且重写父类中的方法
    35         String str3 = test.getDate(new Date()
    36         {
    37 
    38             // 重写父类中的方法
    39             @Override
    40             @Deprecated
    41             public String toLocaleString()
    42             {
    43                 return "Hello: " + super.toLocaleString();
    44             }
    45 
    46         });
    47 
    48         System.out.println(str3);
    49     }
    50 }

            生成的 .class文件中,匿名内部类会生成OuterClass$1.class文件,数字根据是第几个匿名内部类而类推。

  • 相关阅读:
    一口气说出9种分布式ID生成方式,面试官有点懵
    13个Mongodb GUI可视化管理工具,总有一款适合你
    基于mysql-8.0.16-winx64的主从搭建(Windows10系统)
    Windows10安装多个版本的PostgreSQL数据库,但是均没有自动注册Windows服务的解决方法
    Win10安装多个MySQL实例
    内核编译步骤及模块管理
    进程管理类命令
    进程监控类命令
    进程概念介绍
    文件打包压缩
  • 原文地址:https://www.cnblogs.com/dazuihou/p/3571516.html
Copyright © 2020-2023  润新知