0
点赞
收藏
分享

微信扫一扫

JAVA中内部类

草原小黄河 2022-02-18 阅读 55

内部类

1.基本介绍

1.概括
  • 一个类的内部又完整的嵌套了另一个类的结构,被嵌套的类称为内部类,嵌套其他类的类称为外部类,内部类最大的特点就是可以直接访问私有属性
2.基本语法
class Outer{class Inner{}
  }
3.内部类的分类
1.定义在外部类局部位置上
  • 局部内部类(有类名)

    • 可以直接访问外部类的所有成员,包含私有的

    • 不能添加访问修饰符,因为它的地位就是一个局部变量,局部变量是不能使用修饰符的,但是可以使用final修饰,因为局部变量也可以使用final

    • 作用域:仅仅在定义它的方法或代码块中

    • 局部内部类----访问----->外部类的成员 [访问方式 : 直接访问]

    • 外部类—访问----->局部内部类的成员 [访问方式: 创建对象,在访问(注意:必须在作用域中)]

    • 外部其他类-----不能访问----->局部内部类

    • 如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则使用(外部类名.this.成员)去访问

      public class LocalInnerClass {
          public static void main(String[] args) {
              Outer outer = new Outer();
              outer.msg();//10
          }
      }
      class Outer{
          private int age = 10;
          //局部内部类是定义在外部类的局部位置,通常在方法中
          public void msg(){
              class Inner{
                  private int age = 20;
                  //可以直接访问外部类的所有成员,包括私有成员
                  public void getAge(){
                      System.out.println(Outer.this.age);//10
                  }
              }
              Inner inner = new Inner();
              inner.getAge();
          }
      }
      
  • 匿名内部类(没有类名 [重点])

    • 说明:匿名内部类是定义在外部类的局部位置

    • 本质是类,且内部类,同时还是一个对象

    • 匿名内部类的基本语法

      • new 类或接口(参数列表){ 类体 };

        /**
         * 演示匿名内部类的使用
         */
        public class AnonymousInner_ {
            public static void main(String[] args) {
                Outer_4 outer_4 = new Outer_4();
                outer_4.method();//工作ing.....   \n 重写匿名内部类的test方法
            }
        }
        
        //外部类
        class Outer_4{
            private int num_1 = 10;
            public void method(){
                //基于接口的匿名内部类
                //只在此处使用一次
                //worker的编译类型  As_1  worker的运行类型  匿名内部类(底层会分配一个类名,外部类的名称$1)
                /*
                    class Outer_4$1 implements As_1{
                        @Override
                        public void cry() {
                            System.out.println("工作ing.....");
                        }
                    }
                 */
                //JDK底层在创建匿名内部类Outer_4$1,立即就创建了Outer_4$1实例,并且把地址返回给worker
                //匿名内部类只能使用一次
                As_1 worker = new As_1() {
                    @Override
                    public void cry() {
                        System.out.println("工作ing.....");
                    }
                };
                worker.cry();
                /**
                 * 基于类的匿名内部类
                 * 1.father 编译类型 Father
                 * 2.father 运行类型 Outer_4$2
                 * 3.底层会创建匿名内部类
                 * class Outer_4$2 extends Father{
                 *   @Override
                 *   public void test(){
                 *      System.out.println("重写匿名内部类的test方法");
                 *   }
                 * }
                 * 4.同时也直接返回了 内名内部类
                 */
                Father father = new Father("jack"){
                    @Override
                    public void test(){
                        System.out.println("重写匿名内部类的test方法");
                    }
                };
                father.test();
            }
        }
        //接口
        interface As_1{
            public void cry();
        }
        class Father{
            public Father(String name){
                super();
            }
            public void test(){
        
            }
        }
        
    • 匿名内部类的注意事项和细节

      • 匿名内部类既是一个类的定义,同时它本身也是一个对象,语法上看,既有定义类的特征,也有创建对象的特征【代码演示】

        //方式一【推荐使用】
        new A(){
            @Override
            public void test(){
                System.out.println("Hello");
            }
        }.test();
        //方式二
        A a = new A(){
            @Override
            public void test(){
                System.out.println("hello");
            }
        };
        a.test();
        
      • 可以直接访问外部类的所有成员,包含私有的

      • 不能添加访问修饰符,因为它的地位就是一个局部变量

      • 作用域: 仅仅在定义它的方法或代码块中

      • 匿名内部类—访问—>外部类成员 [访问方式: 直接访问]

      • 外部其他类 — 不能访问------>匿名内部类

      • 如果外部类和匿名内部类的成员变量重名时,匿名内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问

2.定义在外部类的成员位置上
  • 成员内部类(没用 static修饰)

    • 说明:成员内部类是定义在外部类的成员位置,并且没有static修饰

    • 可以直接访问外部类的所有成员,包含私有的

    • 可以添加任意修饰符,因为它的地位就是一个成员

      class Outer{
          private int num = 10;
          public String name = "张三";
          //注意:成员内部类是定义在外部类的成员位置上
          class Inner{
              public void say(){
                  System.out.println("成员内部类  num="+num);
              }
          }
      }
      
    • 作用域:和外部类的其他成员一样,在外部类的成员方法中创建成员内部类对象,在调用方法

    • 成员内部类—访问---->外部类[ 直接访问 ]

    • 外部类—访问---->内部类 [创建对象,在访问 ]

    • 外部其他类—访问---->成员内部类

      //方式一
      Outer outer = new Outer();
      Outer.Innter innter = outer.new Innter();
      //方式二
      Innter innter = new Outer().new Innter();
      //方式三
      Innter innter = new Outer().getInnterInstance();
      
    • 如果成员内部类的成员和外部类的成员重名了,遵守就近原则

    • 如果外部类想访问,可以通过 外部类名.this.变量名 来访问

  • 静态内部类(使用static修饰)

    • 说明:静态内部类是定义在外部类的成员位置,并且有static修饰

    • 可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员

    • 可以添加任何修饰符修饰,因为它的地位就是一个成员

    • 作用域:同其他的成员一样,为整个类体

      class Outer{
          private int num = 30;
          public String name = "张三";
          static String username = "root";
          static class Innter{
              private int num = 30;
              public void test_1(){
                  System.out.println("测试类运行");
                  System.out.println("username = "+username);
              }
          }
      }
      
    • 静态内部类 —访问---->外部类 [直接访问所有静态成员]

    • 外部类—访问---->静态内部类 [ 创建内部类对象,在访问 ]

    • 外部其他类—访问—>静态内部类

      //因为静态内部类,是可以通过类直接访问(但是要满足访问权限)
      //方式一
      Outer.Innter innter = new Outer.Innter();
      //方式二 --- 1  静态和非静态都可以使用
      Outer.Innter innter = (new Outer()).getInnter();
      //方式二 --- 2 静态
      Outer.Innter innter = Outer.getInnter();
      
    • 如果外部类静态内部类的成员变量重名,静态内部类访问的时候,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.成员 )去访问

举报

相关推荐

0 条评论