zoukankan      html  css  js  c++  java
  • java基础系列(七):内部类的详解

    为什么使用java内部类?

    使用内部类的一个主要原因:每个内部类都能独立的继承一个类(接口),无论外围类是否已经继承某个类,对内部类没有任何的影响。

    使用内部类的优点:它能非常好的解决多重继承的问题,提供了更好的封装,除了外围类,其他的类都不能访问。

    内部类的使用:

    内部类的使用方式有四种:成员内部类,静态内部类,局部内部类,匿名内部类。接下来分别看一下,内部类的使用方式。

    1.成员内部类

    public class Outer{
            public String name;
            public class Inner{
            public int age;
            public int info(){
              System.out.println("我的年龄是:"+age);
            }
         } }

    注意:

    1. 成员内部类定义在外部类的内部,相当于外部类的一个成员变量的位置,内部类可以像类属性那样被访问控制符修饰。
    2. 内部类可以访问外部类的成员,而不受任何访问控制符的限制,包括直接访问外部类的私有属性。
    3. 创建内部类对象,外部类.内部类 对象名=外部类对象.new 内部类();
    4. 内部类不能存在任何static的变量和方法,可以定义常量。因为静态变量或方法依赖类,不依赖于实例变量,但是内部类是依赖于外部类的实例对象的,这样的话就会产生一个矛盾,编译器不会编译的。
    5. 如果内部类和外部类具有相同的成员变量和方法,内部类默认访问自己的成员变量或方法,如果访问外部类的成员变量,使用这种方式:外部类.this.name。

    问题:为什么成员内部类可以直接访问外部类的属性或方法呢?

      java文件被编译之后,内部类会持有一个外部类的隐式引用,这个引用是编译过程中添加进去的。编译的时候,编译器会给内部类的构造器添加一个外部类的引用,无论使用有参构造器或是无参构造器,这样内部类就可以访问外部类的属性或者方法。这也从侧面说明成员内部类是依赖于外部类的。

    2.静态内部类

    public class Outer{
            public String name;
            public static class Inner{
            public int age;
            public int info(){
              System.out.println("我的年龄是:"+age);
            }
         }
    }
    1. 静态内部类不能直接访问外部类的非静态成员,但是可以通过new 外部类().成员的方式访问
    2. 如果外部类的静态成员与内部类的成员名称相同,可通过类名.静态成员访问外部类的静态成员;如果外部类的静态成员与内部类的成员名称不相同,则可通过成员名直接调用外部类的静态成员。
    3. 创建静态内部类的对象时,不需要外部类的对象,可以直接创建:内部类 对象名 = new 内部类()

    3.局部内部类

    public class Outer{
            public String name;
            public void showinfo(){
                    class Inner{
            public int age;
            public int info(){
              System.out.println("我的年龄是:"+age);
            }
         }
     
            }
            
    }
    1. 局部内部类就像是方法里面的一个局部变量一样,是不能有 public、protected、private 以及 static 修饰符的
    2. 局部内部类只能访问局部final变量,尽管jdk1.8不需要final显式的修饰局部变量,但是编译器仍然是按final变量进行编译的,这点可以通过反编译验证。这个在编译内部类的时候,如果局部变量的值在编译期间可以确定,则会在内部类创建一个拷贝(基本数据类型),如果局部变量的值是无法在编译期间确定,则通过构造器传参的方式来对拷贝进行初始化赋值。使用的形参为什么要用final呢?在内部类中的属性和外部方法的参数两者从外表上看使用一种东西,但是内部类只是持有的一个变量的拷贝而已,内部类属性的改变不会影响到外部形参,但是从程序员的角度看,这就是同一个变量,所以为了保持参数的一致性,就规定使用final来避免形参的不改变。

    4.匿名内部类

    public class Outer{
            public String name;
            public getInner(){
                    return new Innter(){
                            public int getNumber(){
                                 return 123;
                            }
                    };
            }
            interface Inner{
                  int getNumber();
           }
            
    }
    1. 匿名内部类它仅能被使用一次,创建匿名内部类时他会立即船舰一个该类的实例,该类的定义会立即消失。
    2. 使用匿名内部类我们必须继承一个类或实现一个接口,且只能继承一个类或实现一个接口。
    3. 匿名内部类是不能定义构造函数的,匿名内部类中不能存在任何的静态成员变量和静态方法。
    4. 匿名类初始化:使用构造器代码块,利用构造代码块能够达到为匿名内部类创建一个构造器的效果。
  • 相关阅读:
    Orchard源码分析(1):Orchard架构
    抓取网站数据不再是难事了,Fizzler(So Easy)全能搞定
    jQuery版本升级踩坑大全
    ASP.NET MVC使用Bootstrap系列(5)——创建ASP.NET MVC Bootstrap Helpers
    ASP.NET MVC使用Bootstrap系列(4)——使用JavaScript插件
    ASP.NET MVC使用Bootstrap系统(2)——使用Bootstrap CSS和HTML元素
    ASP.NET MVC使用Bootstrap系列(3)——使用Bootstrap 组件
    ASP.NET MVC使用Bootstrap系列(1)——开始使用Bootstrap
    Entity Framework数据库初始化四种策略
    WCF、WebAPI、WCFREST、WebService之间的区别
  • 原文地址:https://www.cnblogs.com/amazing-eight/p/13395937.html
Copyright © 2011-2022 走看看