今天聊一下几行代码带你彻底搞懂Java内部类

内部类

基本概述


  • 当一个类的定义放在另一个类的实体时,则该类叫做内部类,该类所在的类叫做外部类
  • 在一个类体中可以出现的内容:成员变量、成员方法、构造方法、构造块、静态语句块、静态变量、方法、内部类
  • 嵌套类
    – 内部类(成员内部类、局部内部类、匿名内部类)
    – 静态嵌套类

语法格式

class 外部类类名{

	class 内部类类名{

		内部类类体;

	}

}

成员内部类


  • 成员内部类定义在另一个类或接口中的内部类
  • 注意事项
    – 必须先创建外部类对象才能创建成员内部类对象
    – 不能含有静态变量、静态代码块、静态方法(除了静态常量)
    – 外部类可以通过成员内部类的对象调用内部类私有成员
    – 成员内部类是一个独立的类,编译成独立的.class文件
  • 作用
    – 成员内部类既可以访问外部类信息,又可以访问父类信息,从而使得多继承的解决方案变得完整
  • 案例
    – Outer.java “`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
```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 “`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
```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 “`java
    public interface InterDemo {
	public abstract void print();

}

```

- Outer.java
```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
```java
public class TestOuter {

	public static void main(String[] args) {

		Outer o = new Outer();

		o.show();

	}

}

```

	匿名内部类str1

	Outer类中str2

	Outer类中str1

静态嵌套类


  • 静态嵌套类定义在另一个类、接口 、使用static关键字修饰的嵌套类
  • 注意事项
    – 不需要生成外部类对象来生成静态嵌套类对象
    – 只能直接访问外部类的静态成员
    – 外部类可以通过静态嵌套类的对象调用内部类的成员
    – 可以定义静态成员变量或静态成员方法
  • 案例
    – Outer.java “`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
```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方法

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

名称 | 内部类(非静态嵌套类) | 静态嵌套类

  • | – | –
    定义位置上 | 成员位置、方法、代码块 | 只能在外部类的成员位置
    组成 | 实例成员、静态常量、构造方法 | 实例成员、静态成员、静态代码块、构造方法
    对象创建 | 必须先有外部类的对象 | 不依赖于外部类实例,可以直接实例化
    访问外部类 | 可以直接访问外部类所有成员 | 只能直接访问外部类的静态成员

喜欢就关注博主博吧 今天聊一下几行代码带你彻底搞懂Java内部类

正文完