关于思否技术征文:几行代码带你彻底搞懂Java内部类

本文参加了思否技术征文,欢送正在浏览的你也退出。

外部类

根本概述


  • 当一个类的定义放在另一个类的实体时,则该类叫做外部类,该类所在的类叫做外部类
  • 在一个类体中能够呈现的内容:成员变量、成员办法、构造方法、结构块、动态语句块、动态变量、办法、外部类
  • 嵌套类

    • 外部类(成员外部类、部分外部类、匿名外部类)
    • 动态嵌套类

语法格局

class 外部类类名{
    class 外部类类名{
        外部类类体;
    }
}

成员外部类


  • 成员外部类定义在另一个类或接口中的外部类
  • 注意事项

    • 必须先创立外部类对象能力创立成员外部类对象
    • 不能含有动态变量、动态代码块、静态方法(除了动态常量)
    • 外部类能够通过成员外部类的对象调用外部类公有成员
    • 成员外部类是一个独立的类,编译成独立的.class文件
  • 作用

    • 成员外部类既能够拜访外部类信息,又能够拜访父类信息,从而使得多继承的解决方案变得残缺
  • 案例

    • Outer.java

      // 成员外部类的应用
      public class Outer { // 外部类
      
      private String str = "Outer类的str1";
      private String str2 = "Outer类的str2";
      
      /*
       * 第一:外部类的名称不能与外部类重名
       * 第二:能够应用final、拜访修饰符润饰
       */
      public class Inner{ // 外部类
      
          private String str = "Inner类的str1";
          private String str2 = "Inner类的str2";
          
          public void show() {
              // 外部类的成员优先于外部类成员
              System.out.println(str);
              System.out.println(str2);
              
              // 应用"外部类.this.成员"拜访外部类的成员
              System.out.println(Outer.this.str2);
              System.out.println(Outer.this.str);
          }
          
      }
      
      }
    • TestOuter.java

      import Inner.demo1.Outer.Inner;
      
      public class TestOuter {
      
      public static void main(String[] args) {
          // 如果要创立外部类,那么在此之前须要先创立外部类对象
          
          // 创立外部类对象
          Outer o = new Outer();
      
          // 创立外部类
          Inner inner = o.new Inner();
          inner.show();
          
      }
      }

      Inner类的str1
      Inner类的str2
      Outer类的str2
      Outer类的str1

部分外部类


  • 部分外部类是定义在办法h或代码块里的外部类
  • 注意事项:

    • 不能含有动态变量,动态代码块、静态方法
    • 只能在定义该类的办法或代码块中应用,必须在应用前定义
    • 拜访它所有办法的局部变量的时候,j局部变量必须是无效的常量
    • 是一个独立的类,编译成独立的.class文件
    • 只能应用abstract、final润饰
    • 定义动态块或办法时候,只能拜访外部类的动态成员
  • 案例

    • Outer.java

      // 部分外部类
      public class Outer { // 外部类
      
      private String str1 = "Outer类中的str1";
      private String str2 = "Outer类中的str2";
      
      // 定义一个外部类的办法
      public void print() {
          System.out.println("Outer类中的print办法");
      }
      
      static {
          class Inner{}  // 部分外部类
      }
      
      public void method() {
          
          // 必须在应用之前定义 
          class Inner{
              private String str1 = "Inner类中的str1";
              
              // 外部类成员优先于外部类成员
              public void visitOuter() {
                  System.out.println(str1);
                  System.out.println(str2);
                  print();  // 间接跳到外部类办法
              }
          }
          
          // 部分外部类只能在定义它的办法或代码块中应用
          // 只能应用abstract/final润饰,不能与外部类重名
          Inner in = new Inner();
          in.visitOuter();
      }
      }
    • TestOuter.java

      public class TestOuter {
      
      public static void main(String[] args) {
          
          Outer o = new Outer();
          o.method();
      }
      }

      Inner类中的str1
      Outer类中的str2
      Outer类中的print办法

匿名外部类


  • 匿名外部类是间接应用接口或父类实例化时创立没有名字的外部类
  • 语法格局

    • 接口/父类类型 援用名 = new 接口/父类类型(){
      进行办法的重写;
      }
  • 注意事项

    • 必须且仅能继承一个父类或实现一个接口
    • 没有class关键字、没有类名
    • 是非凡的部分外部类
    • 仅能应用一次
    • 不能定义构造方法
    • 匿名类不能是抽象类
  • 长处以及作用

    • 匿名外部类能够使代码更加紧凑、简洁
    • 封装性比拟好
    • 匿名外部类能够灵便的创立
    • 匿名外部类使得多继承的解决方案比拟残缺
  • 案例

    • InterDemo.java

      public interface InterDemo {
      
      public abstract void print();
      }
    • Outer.java

      public class Outer { // 外部类
      
      private String str1 = "Outer类中str1";
      private String str2 = "Outer类中str2";
      
      // 匿名外部类
      InterDemo id = new InterDemo() {
          
          private String str1 = "匿名外部类str1";
          
          @Override
          public void print() {
          
              System.out.println(str1);
              System.out.println(str2);
              
              // 如果想要调用外部类的变量 ,  外部类.this.变量
              System.out.println(Outer.this.str1);
          }
      };
      
      public void show() {
          id.print();
      }
      }
    • TestOuter.java

      public class TestOuter {
      
      public static void main(String[] args) {
          
          Outer o = new Outer();
          o.show();
      }
      }

      匿名外部类str1
      Outer类中str2
      Outer类中str1

动态嵌套类


  • 动态嵌套类定义在另一个类、接口 、应用static关键字润饰的嵌套类
  • 注意事项

    • 不须要生成外部类对象来生成动态嵌套类对象
    • 只能间接拜访外部类的动态成员
    • 外部类能够通过动态嵌套类的对象调用外部类的成员
    • 能够定义动态成员变量或动态成员办法
  • 案例

    • Outer.java

      public class Outer { // 外部类 
      
      // 创立两个成员变量   一个动态,一个非动态
      private String str1 = "外部类的str1";
      private static String str2 = "外部类的str2";
      
      // 成员办法,动态
       public static void show1() {
          System.out.println("外部类的show办法");
      }
      
      // 动态嵌套类
      // 只能定义在类的成员地位,不能定义在办法或代码块中
      public static class Inner{
          
          private String str1 = "嵌套类的str1";
          // private static String str2 = "嵌套类的str2";
          
          public void show() {
              System.out.println(str2);
              System.out.println(str1);
              
              // 不能间接拜访外部类的非动态成员
              // 然而能够间接拜访外部类的动态成员
              show1();
          }
      
      }
      
      }
    • TestOuter.java

      import Inner.demo4.Outer.Inner;
      
      public class TestOuter {
      public static void main(String[] args) {
          
          // 如何创立外部类或者动态嵌套类对象
          // 首先创立外部类的对象
          Inner Inner = new Outer.Inner();
          Inner.show();
      }
      
      }

      外部类的str2
      嵌套类的str1
      外部类的show办法

动态嵌套类和非动态嵌套类的区别

名称 外部类(非动态嵌套类) 动态嵌套类
定义地位上 成员地位、办法、代码块 只能在外部类的成员地位
组成 实例成员、动态常量、构造方法 实例成员、动态成员、动态代码块、构造方法
对象创立 必须先有外部类的对象 不依赖于外部类实例,能够间接实例化
拜访外部类 能够间接拜访外部类所有成员 只能间接拜访外部类的动态成员

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理