写点什么

几行代码带你彻底搞懂 Java 内部类

用户头像
若尘
关注
发布于: 2021 年 06 月 14 日
几行代码带你彻底搞懂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方法
复制代码

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

定义位置上 | 成员位置、方法、代码块 | 只能在外部类的成员位置

组成 | 实例成员、静态常量、构造方法 | 实例成员、静态成员、静态代码块、构造方法

对象创建 | 必须先有外部类的对象 | 不依赖于外部类实例,可以直接实例化

访问外部类 | 可以直接访问外部类所有成员 | 只能直接访问外部类的静态成员


发布于: 2021 年 06 月 14 日阅读数: 36
用户头像

若尘

关注

还未添加个人签名 2021.01.11 加入

还未添加个人简介

评论

发布
暂无评论
几行代码带你彻底搞懂Java内部类