`
new_Line
  • 浏览: 9735 次
  • 性别: 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培训、期待与您交流! ----------

分享到:
评论

相关推荐

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

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

    BasicJava_java_

    Java基础编程Day01-11,黑马程序员内部绝密编程课程,快速成为Java程序员

    黑马程序员入学测试题详解

    3、 方法中的内部类能不能访问方法中的局部变量,为什么? 4、 定义一个交通灯枚举,包含红灯、绿灯、黄灯,需要有获得下一个灯的方法,例如:红灯获取下一个灯是绿灯,绿灯获取下一个灯是黄灯。 5、 编写...

    javase基础练习_模拟电影购票系统_黑马课程

    Ⅳ.lambda表达式遍历集合,以及比较器comparator()匿名内部类的使用 V.使用Stream流操纵集合 功能: ①日志框架搭建、系统角色设计 ②首页、登录、商家界面、用户界面实现 ③商家功能-展示详情、影片上架、退出 ④...

    黑马程序员 黑马 数据结构与算法 课件 源代码.zip

    算法与数据结构它们分别涵盖了以下主要内容: 数据结构(Data Structures): ...学习算法与数据结构不仅有助于理解程序的内部工作原理,更能帮助开发人员编写出高效、稳定和易于维护的软件系统。

    黑马内部复习面试资料

    文件为黑马程序员老师整理的复习和面试准备的资料。包括java基础复习和面试宝典。

    Java基础最全笔记文档

    3. 多态、内部类、常用API 4. 日期与时间、日期类、包装类、正则表达式、Arrays 类、常见算法、Lambda 表达式 5. Collection集合、数据结构、List集合、泛型、Set集合、可变参数 6. 集合工具类Collections、Map集合...

    JAVA面试宝典

    程序员面试宝典!该宝典为黑马程序员内部资料,对面试中的各种技术问题给出了详细的解答,

    黑马入学考试试题

    黑马程序员训练营入学考试题 1、方法中的内部类能不能访问方法中的局部变量,为什么? 2、编写一个类,在main方法中定义一个Map对象(采用泛型),加入若干个对象,然后遍历并打印出各元素的key和value。 ...

    WEB开发入门

    这是黑马程序员内部,方立勋大牛讲解的web开发入门ppt文档,很有借鉴价值。

    javase总结

    笔记来源于黑马程序员内部总结,总结的非常全面很适合懒人学者的学习和复习

    javaweb文件上传与下载模块源代码

    javaweb文件上传与下载模块源代码 详见内部说明书 适合于初学者,JAVA程序员收藏

Global site tag (gtag.js) - Google Analytics