`
new_Line
  • 浏览: 10284 次
  • 性别: Icon_minigender_1
最近访客 更多访客>>
社区版块
存档分类
最新评论

黑马程序员_java内部类

 
阅读更多

------- android培训java培训、期待与您交流! ----------

概述:
    将类定义在一个类的内部,这个定义在其他类内部的类称为内部类,包含内部类的类称为外部类。
    Java从JDK1.1开始引入内部类。
格式举例:
    public class Outer{
        private class Inner{}
    }
内部类的作用:
    1、内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类
    2、内部类成员可以直接访问外部类的成员,包括私有数据,因为内部类被当成其外部类成员,
       同一个类的成员之间可以相互访问。但外部类不能访问内部类的实现细节
    3、匿名内部类适合用于创建那些仅需一次使用的类
访问特点:
    1、内部类可以直接访问外部类的成员,包括私有成员
      2、外部类要访问内部类中的成员必须创建内部类对象
内部类的分类:
    内部类又分为成员内部类和局部内部类。
    成员内部类是一种和属性、方法、构造器和初始化块的类成员,局部内部类和匿名内部类不是类成员。
    成员内部类又分为两种:静态内部类和非静态内部类,使用static修饰的成员内部类是静态内部类。
非静态内部类:
        非静态内部类作为外部类,所以可以使用任意访问修饰符如public、private、protect等修饰。
    因为此类型内部类的上一程序单元是外部类,它就具有4个作用域:同一个类,同一个包,父子类和
    任何位置,因此可以使用4中访问修饰符。
      非静态内部类里可以直接访问外部类的成员,包括私有成员,当在非静态内部类访问某个变量时,
    优先级从内而外:内部类方法的局部变量>内部类的成员变量>外部类的成员变量。
        因此,如果外部类的成员变量、内部类的成员变量、内部类方法里的局部变量同名,则可以通过
        使用外部类类名.this.、this作为限定来区分。而如果在外部类想要访问内部类则必须在外部类中
        创建非静态内部类对象,根据静态不能访问非静态成员的原则,不允许在外部类的静态成员中直接
        使用非静态内部类。
        演示:
            public class OuterClass {
                String str = "这是外部类中的属性";
                private class InnerClass
                {
                    String str = "这是内部类中的属性";
                    /**
                     * 打印外部类成员和内部类成员的方法
                     */
                    public void showField()
                    {
                        String str = "这是局部变量";
                        System.out.println("访问外部类成员:"
                            + OuterClass.this.str);
                        System.out.println("访问内部类成员:" + this.str);
                        System.out.println("访问内部类方法中的局部变量:"
                            + str);
                    }
                }
                /**
                 * 创建访问内部类的方法
                 */
                public void visitInnerClass() //如果加上static修饰,编译不通过
                {
                    //创建内部类对象
                    InnerClass in = new InnerClass();
                    //调用打印方法
                    in.showField();
                }
                public static void main(String[] args) {
                    //创建外部类对象
                    OuterClass oc = new OuterClass();
                    oc.visitInnerClass();
                }
            }
        编译上面程序,看到在文件所在路径生成了两个class文件,一个是OuterClass.class,
        另一个是OuterClass$InnerClass.class,前者是外部类的文件,后者是内部类文件,
        即成员内部类(包括静态和非静态)的class文件形式:外部类名$内部类名.class。
    Java不允许在非静态内部类里定义静态成员,否则编译出错。
        演示说明:
            public class Outer{
                private class Inner{
                    //下面三个静态声明都将引发编译错误
                    static{}
                    private static int a;
                    private static void show(){}
                }
            }
    在外部类以外使用非静态内部类,则非静态内部类不能使用private修饰。语法如下:
        外部类名.内部类名 标识符 = new 外部类名().new 内部类名();
        演示:
            public class Outer {
                public class Inner
                {
                    public void show()
                    {
                        System.out.println("这是内部类");
                    }
                }
            }
            public class Test{
                public static void main(String[] args) {
                    //在外部类以外创建内部类对象
                    Outer.Inner in = new Outer().new Inner();
                    in.show();
                }
            }
静态内部类:
    使用static来修饰的成员内部类称为静态内部类。根据静态成员不能访问非静态的成员的规则,
    静态内部类不能访问外部类的实例成员,只能访问外部类的类成员(static修饰)。
    即使是在静态内部类的实例方法也不能访问外部类的实例成员。
        演示:
            public class Outer{
                private  int age = 0;
                private static class Inner{
                    public void show()
                    {
                        System.out.println(age); //编译出错
                    }
                }
            }
    静态内部类里也可以直接访问外部类的静态成员,当在静态内部类访问某个静态属性时,
    优先级也是从内而外:内部类的静态成员变量>外部类的静态成员变量。
    因此,如果外部类的静态成员变量、内部类的静态成员变量同名,则可以通过使用
    外部类类名.变量名、内部类名.变量名作为限定来区分。
        演示:
            public class Outer {
                static String str = "这是外部类中的属性";
                private static class Inner
                {
                    private static String str = "这是内部类中的属性";
                    /**
                     * 打印外部类成员和内部类成员的方法
                     */
                    public void showField()
                    {
                        //System.out.println(age);
                         String str = "这是局部变量";
                        System.out.println("访问外部类成员:" + Outer.str);
                        System.out.println("访问内部类成员:" + Inner.str);
                        System.out.println("访问内部类方法中的局部变量:"
                            + str);
                    }
                }
                /**
                 * 创建访问内部类的方法
                 */
                public static void visitInnerClass()
                {
                    //创建内部类对象
                    Inner in = new Inner();
                    //调用打印方法
                    in.showField();
                }
                public static void main(String[] args) {
                    //创建外部类对象
                    Outer oc = new Outer();
                    oc.visitInnerClass();
                }
            }
    在外部类以外使用静态内部类,内部类也不能用private修饰,语法如下:
        外部类名.内部类名 标识符 = new 外部类名.内部类名();
        演示:
            public class Outer {
                public static class Inner
                {
                    public void show()
                    {
                        System.out.println("这是内部类");
                    }
                }
            }
            public class Test{
                public static void main(String[] args) {
                    Outer.Inner in = new Outer.Inner();
                    in.show();
                }
            }
局部内部类:
    如果把一个内部类放在方法里定义,则这个内部类就是一个局部内部类,局部内部类仅在该方法里有效。
    因此局部内部类不能使用任何修饰符,如果需要使用局部内部类定义变量、创建实例或派生子类,
    那么都只能在局部内部类所在的方法内进行。
        演示:
            Public class Outer{
                  public static void main(String[] args){
                      Class Inner{
                          Int a;
                    }
                      Class InnerSub extends Inner{
                          Int b;
                      }
                      Inner i = new InnerSub();
                      i.a = 8;
                  }
              }
    编译上面程序,生成了三个class文件:Outer.class、Outer$1Inner.class、Outer$1InnerSub.class。
    局部内部类的class文件比成员内部类的class文件多了一个数字,这是因为同一个类里不可能有两个
    同名的成员内部类,而同一个类里则可能有一个以上同名的局部内部类(处于不同的方法中),
    所以java为局部内部类的class文件名中增加了一个数字,作为区分。
匿名内部类:
    匿名内部类适合创建只需一次使用的类,定义匿名内部类的格式如下:
        new 父类构造器(实参列表) 或者 实现接口()
        {
            //实体部分
        }
         从定义格式可以看出,匿名内部类必须继承一个父类,或实现一个接口,有且继承或实现一个。
    关于内部类的两条规则:
        1:匿名内部类不能是抽象类,因为在创建匿名内部类的同时,会立即创建匿名内部类的对象,
           因此不允许将匿名内部类定义成抽象类
        2:匿名内部类不能定义构造器。因为匿名内部类没有类名。但可以定义实例初始化块。
    匿名内部类最常见的创建方式是定义在接口中,
        演示:
            public class FileTest {
                  public static void main(String[] args) {
                      File file = new File("h:");
                      String[] strArr = file.list(new FilenameFilter()
                      {
                          public boolean accept(File dir, String name) {
                              return new File(dir, name).isFile() &&
                                name.endsWith(".java");
                          }
                      });
                      for(String item : strArr)
                      {
                          System.out.println(item);
                      }
                  }
            }
    注意事项:
        当创建匿名内部类是,必须实现接口或抽象父类里的所有抽象方法。如果匿名内部类和
        局部内部类里需要访问外部类的局部变量,则必须使用final修饰符来修饰外部类的局部变量。
        演示:
            public class OuterClass {
                public static void main(String[] args)
                {
                    final int a = 20;
                    class InnerClass
                    {
                        public void show()
                        {
                            //如果不加final,此处报错
                            System.out.println(a);
                        }
                    }
                }
            }   

------- android培训java培训、期待与您交流! ----------

分享到:
评论

相关推荐

    黑马程序员_java8新特性详解笔记和源码

    Java 8是Java语言发展的一个重要里程碑,引入了许多创新性的特性和改进,...黑马程序员的Java8新特性详解笔记和源码提供了深入学习这些概念的资源,结合实际的代码示例,将有助于你更好地理解和掌握Java 8的核心特性。

    黑马程序员_毕向东_Java基础视频教程第18天-09-IO流(文件的续写)

    黑马程序员_毕向东_Java基础视频教程第18天-09-IO流(文件的续写)

    01_黑马程序员_张孝祥_Java基础加强_课程价值与目标介绍.zip

    【标题】"01_黑马程序员_张孝祥_Java基础加强_课程价值与目标介绍.zip" 提供的是一门由黑马程序员机构推出的Java基础强化课程,由讲师张孝祥主讲,旨在深入讲解Java编程的基础知识并进行能力提升。 【描述】中提到...

    黑马程序员_毕向东_Java基础视频教程第22天-06-GUI(Action事件).zip

    在本视频教程“黑马程序员_毕向东_Java基础视频教程第22天-06-GUI(Action事件)”中,讲师毕向东深入讲解了Java GUI中的Action事件处理机制,这是构建用户友好界面的关键部分。 首先,我们要理解什么是GUI。GUI,...

    黑马程序员_Java基础辅导班教程课件[第01期]第7天

    1. **类与对象**:Java是一种面向对象的语言,因此理解类和对象的概念至关重要。类是对象的蓝图,定义了对象的属性(字段)和行为(方法)。而对象则是类的实例,具备类定义的所有特征和功能。 2. **封装**:封装是...

    黑马程序员入学Java精华总结

    ### 黑马程序员入学Java精华总结 #### 一、Java概述与基础知识 1. **何为编程?** - 编程是指通过编写计算机能够理解的指令来解决问题或完成特定任务的过程。这些指令通常被组织成算法,并使用某种编程语言实现。...

    黑马程序员Javase笔记

    "黑马程序员Javase笔记"是一个自学者在学习黑马程序员提供的Java全套课程过程中整理的笔记,主要涵盖了Java Standard Edition (Javase) 的核心内容。下面将详细讨论其中的关键知识点。 首先,DOS命令是操作系统中的...

    黑马程序员入学Java知识(精华总结)

    ### 黑马程序员入学Java知识(精华总结) #### 一、Java概述与基础知识 ##### 1、何为编程? 编程是指使用计算机语言来编写指令,这些指令被计算机执行以完成特定任务的过程。通过编程,我们可以控制计算机的行为...

    黑马程序员入学面试题

    - `classpath`:用于指定Java程序在运行时的类搜索路径,包括程序类和第三方库类的位置。 ### 第三部分面试题 #### 47. collection和collections的区别 - `Collection`:接口,是Java集合框架的基础接口之一。 - `...

    java并发库高级应用源码--张孝祥

    Java提供了多种线程安全的数据结构,如`Atomic`系列类、`ConcurrentHashMap`等,它们在内部实现了线程安全,避免了外部同步的需要。 线程锁技术包括内置锁(也称为监视器锁)和显式锁。内置锁是`synchronized`的...

    Java-IO流高级-例题 & 例题源码 & PPT教学文档(黑马程序员详细版).rar

    本资料包“Java-IO流高级-例题 & 例题源码 & PPT教学文档(黑马程序员详细版).rar”提供了一个深入学习Java IO流的全面资源,包含实例题目、源代码以及PPT教学材料,适合对Java IO有进阶需求的开发者。 1. **Java ...

    黑马程序员入学Java知识

    ### 黑马程序员入学Java知识 #### Java概述与基础知识 1. **何为编程?** - 编程是通过特定的计算机语言来编写指令,让计算机执行一系列任务的过程。 2. **Java语言概述,历史、特点** - **概述**:Java是一种...

    Java-集合的例题 & 例题源码 & PPT教学文档(黑马程序员详细版).rar

    本资料包是黑马程序员提供的详细教程,涵盖了Java集合的例题、源码以及配套的PPT教学文档,旨在帮助学习者深入理解和掌握Java集合的使用。 首先,我们来探讨Java集合框架的基本概念。Java集合框架包括接口和实现类...

    黑马程序员JAVA面试宝典2018年5月最新版

    《黑马程序员JAVA面试宝典2018年5月最新版》是一本专门为Java开发者准备的面试指南,它集合了2018年5月时最新的面试知识点和业界趋势,旨在帮助Java程序员在求职过程中更好地应对各类技术面试。这本书可能涵盖了Java...

    集合-黑马程序员Java学习笔记

    本学习笔记由黑马程序员提供,旨在帮助初学者深入理解Java中的集合框架及其使用方法。 首先,我们来探讨“集合”的基本概念。在Java中,集合是一个对象容器,可以容纳多个元素,这些元素可以是任意类型的数据。Java...

    2014黑马程序员JAVA基础测试题

    在内部类中可以直接使用外部类的成员,而在外部类中,需要通过创建内部类的对象来调用内部类的方法。 9. 拷贝.java文件并修改扩展名:可以使用Java的File和FileInputStream、FileOutputStream类,配合FileVisitor...

    JAVA第三章的课后习题答案

    类是Java中构造对象的蓝图,定义了对象的状态(数据成员)和行为(方法)。对象则是类的实例,它具有类定义的属性和行为。封装是面向对象的核心特性之一,通过访问控制修饰符(public, private, protected)实现数据...

    黑马java教程知识点笔记整理

    【Java编程基础】 ...以上是黑马Java教程知识点笔记的主要内容,涵盖了Java编程的基础到进阶知识,是学习和巩固Java技能的重要参考资料。通过深入理解和实践这些知识点,开发者可以逐步提升Java编程能力。

Global site tag (gtag.js) - Google Analytics