前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >几行代码带你彻底搞懂Java内部类

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

原创
作者头像
ruochen
修改2021-05-17 10:20:53
5640
修改2021-05-17 10:20:53
举报

内部类

基本概述


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

语法格式

代码语言:txt
复制
class 外部类类名{
代码语言:txt
复制
	class 内部类类名{
代码语言:txt
复制
		内部类类体;
代码语言:txt
复制
	}
代码语言:txt
复制
}

成员内部类


  • 成员内部类定义在另一个类或接口中的内部类
  • 注意事项 - 必须先创建外部类对象才能创建成员内部类对象 - 不能含有静态变量、静态代码块、静态方法(除了静态常量) - 外部类可以通过成员内部类的对象调用内部类私有成员 - 成员内部类是一个独立的类,编译成独立的.class文件
  • 作用 - 成员内部类既可以访问外部类信息,又可以访问父类信息,从而使得多继承的解决方案变得完整
  • 案例 - Outer.java ```java // 成员内部类的使用 public class Outer { // 外部类
代码语言:txt
复制
	private String str = "Outer类的str1";
代码语言:txt
复制
	private String str2 = "Outer类的str2";
代码语言:txt
复制
	/*
代码语言:txt
复制
	 * 第一:内部类的名称不能与外部类重名
	 * 第二:可以使用final、访问修饰符修饰
	 */
	public class Inner{ // 内部类
代码语言:txt
复制
		private String str = "Inner类的str1";
代码语言:txt
复制
		private String str2 = "Inner类的str2";
代码语言:txt
复制
		public void show() {
代码语言:txt
复制
			// 内部类的成员优先于外部类成员
代码语言:txt
复制
			System.out.println(str);
代码语言:txt
复制
			System.out.println(str2);
代码语言:txt
复制
			// 使用"外部类.this.成员"访问外部类的成员
代码语言:txt
复制
			System.out.println(Outer.this.str2);
代码语言:txt
复制
			System.out.println(Outer.this.str);
代码语言:txt
复制
		}
代码语言:txt
复制
	}
代码语言:txt
复制
}
代码语言:txt
复制
```
代码语言:txt
复制
- TestOuter.java
```java
import Inner.demo1.Outer.Inner;
代码语言:txt
复制
public class TestOuter {
代码语言:txt
复制
	public static void main(String[] args) {
代码语言:txt
复制
		// 如果要创建内部类,那么在此之前需要先创建外部类对象
代码语言:txt
复制
		// 创建外部类对象
代码语言:txt
复制
		Outer o = new Outer();
代码语言:txt
复制
		// 创建内部类
代码语言:txt
复制
		Inner inner = o.new Inner();
代码语言:txt
复制
		inner.show();
代码语言:txt
复制
	}
代码语言:txt
复制
}
代码语言:txt
复制
```
代码语言:txt
复制
	Inner类的str1
代码语言:txt
复制
	Inner类的str2
代码语言:txt
复制
	Outer类的str2
代码语言:txt
复制
	Outer类的str1

局部内部类


  • 局部内部类是定义在方法h或代码块里的内部类
  • 注意事项: - 不能含有静态变量,静态代码块、静态方法 - 只能在定义该类的方法或代码块中使用,必须在使用前定义 - 访问它所有方法的局部变量的时候,j局部变量必须是有效的常量 - 是一个独立的类,编译成独立的.class文件 - 只能使用abstract、final修饰 - 定义静态块或方法时候,只能访问外部类的静态成员
  • 案例 - Outer.java ```java // 局部内部类 public class Outer { // 外部类
代码语言:txt
复制
	private String str1 = "Outer类中的str1";
代码语言:txt
复制
	private String str2 = "Outer类中的str2";
代码语言:txt
复制
	// 定义一个外部类的方法
代码语言:txt
复制
	public void print() {
代码语言:txt
复制
		System.out.println("Outer类中的print方法");
代码语言:txt
复制
	}
代码语言:txt
复制
	static {
代码语言:txt
复制
		class Inner{}  // 局部内部类
代码语言:txt
复制
	}
代码语言:txt
复制
	public void method() {
代码语言:txt
复制
		// 必须在使用之前定义 
代码语言:txt
复制
		class Inner{
代码语言:txt
复制
			private String str1 = "Inner类中的str1";
代码语言:txt
复制
			// 内部类成员优先于外部类成员
代码语言:txt
复制
			public void visitOuter() {
代码语言:txt
复制
				System.out.println(str1);
代码语言:txt
复制
				System.out.println(str2);
代码语言:txt
复制
				print();  // 直接跳到外部类方法
代码语言:txt
复制
			}
代码语言:txt
复制
		}
代码语言:txt
复制
		// 局部内部类只能在定义它的方法或代码块中使用
代码语言:txt
复制
		// 只能使用abstract/final修饰,不能与外部类重名
代码语言:txt
复制
		Inner in = new Inner();
代码语言:txt
复制
		in.visitOuter();
代码语言:txt
复制
	}
代码语言:txt
复制
}
代码语言:txt
复制
```
代码语言:txt
复制
- TestOuter.java
```java
public class TestOuter {
代码语言:txt
复制
	public static void main(String[] args) {
代码语言:txt
复制
		Outer o = new Outer();
代码语言:txt
复制
		o.method();
代码语言:txt
复制
	}
代码语言:txt
复制
}
代码语言:txt
复制
```
代码语言:txt
复制
	Inner类中的str1
代码语言:txt
复制
	Outer类中的str2
代码语言:txt
复制
	Outer类中的print方法

匿名内部类


  • 匿名内部类是直接使用接口或父类实例化时创建没有名字的内部类
  • 语法格式 - 接口/父类类型 引用名 = new 接口/父类类型(){ 进行方法的重写; }
  • 注意事项 - 必须且仅能继承一个父类或实现一个接口 - 没有class关键字、没有类名 - 是特殊的局部内部类 - 仅能使用一次 - 不能定义构造方法 - 匿名类不能是抽象类
  • 优点以及作用 - 匿名内部类可以使代码更加紧凑、简洁 - 封装性比较好 - 匿名内部类可以灵活的创建 - 匿名内部类使得多继承的解决方案比较完整
  • 案例 - InterDemo.java ```java public interface InterDemo {
代码语言:txt
复制
	public abstract void print();
代码语言:txt
复制
}
代码语言:txt
复制
```
代码语言:txt
复制
- Outer.java
```java
public class Outer { // 外部类
代码语言:txt
复制
	private String str1 = "Outer类中str1";
代码语言:txt
复制
	private String str2 = "Outer类中str2";
代码语言:txt
复制
	// 匿名内部类
代码语言:txt
复制
	InterDemo id = new InterDemo() {
代码语言:txt
复制
		private String str1 = "匿名内部类str1";
代码语言:txt
复制
		@Override
代码语言:txt
复制
		public void print() {
代码语言:txt
复制
			System.out.println(str1);
代码语言:txt
复制
			System.out.println(str2);
代码语言:txt
复制
			// 如果想要调用外部类的变量 ,  外部类.this.变量
代码语言:txt
复制
			System.out.println(Outer.this.str1);
代码语言:txt
复制
		}
代码语言:txt
复制
	};
代码语言:txt
复制
	public void show() {
代码语言:txt
复制
		id.print();
代码语言:txt
复制
	}
代码语言:txt
复制
}
代码语言:txt
复制
```
代码语言:txt
复制
- TestOuter.java
```java
public class TestOuter {
代码语言:txt
复制
	public static void main(String[] args) {
代码语言:txt
复制
		Outer o = new Outer();
代码语言:txt
复制
		o.show();
代码语言:txt
复制
	}
代码语言:txt
复制
}
代码语言:txt
复制
```
代码语言:txt
复制
	匿名内部类str1
代码语言:txt
复制
	Outer类中str2
代码语言:txt
复制
	Outer类中str1

静态嵌套类


  • 静态嵌套类定义在另一个类、接口 、使用static关键字修饰的嵌套类
  • 注意事项 - 不需要生成外部类对象来生成静态嵌套类对象 - 只能直接访问外部类的静态成员 - 外部类可以通过静态嵌套类的对象调用内部类的成员 - 可以定义静态成员变量或静态成员方法
  • 案例 - Outer.java ```java public class Outer { // 外部类
代码语言:txt
复制
	// 创建两个成员变量   一个静态,一个非静态
代码语言:txt
复制
	private String str1 = "外部类的str1";
代码语言:txt
复制
	private static String str2 = "外部类的str2";
代码语言:txt
复制
	// 成员方法,静态
代码语言:txt
复制
 	public static void show1() {
代码语言:txt
复制
		System.out.println("外部类的show方法");
代码语言:txt
复制
	}
代码语言:txt
复制
	// 静态嵌套类
代码语言:txt
复制
	// 只能定义在类的成员位置,不能定义在方法或代码块中
代码语言:txt
复制
	public static class Inner{
代码语言:txt
复制
		private String str1 = "嵌套类的str1";
代码语言:txt
复制
		// private static String str2 = "嵌套类的str2";
代码语言:txt
复制
		public void show() {
代码语言:txt
复制
			System.out.println(str2);
代码语言:txt
复制
			System.out.println(str1);
代码语言:txt
复制
			// 不能直接访问外部类的非静态成员
代码语言:txt
复制
			// 但是可以直接访问外部类的静态成员
代码语言:txt
复制
			show1();
代码语言:txt
复制
		}
代码语言:txt
复制
	}
代码语言:txt
复制
}
代码语言:txt
复制
```
代码语言:txt
复制
- TestOuter.java
```java
import Inner.demo4.Outer.Inner;
代码语言:txt
复制
public class TestOuter {
代码语言:txt
复制
	public static void main(String[] args) {
代码语言:txt
复制
		// 如何创建内部类或者静态嵌套类对象
代码语言:txt
复制
		// 首先创建外部类的对象
代码语言:txt
复制
		Inner Inner = new Outer.Inner();
代码语言:txt
复制
		Inner.show();
代码语言:txt
复制
	}
代码语言:txt
复制
}
代码语言:txt
复制
```
代码语言:txt
复制
	外部类的str2
代码语言:txt
复制
	嵌套类的str1
代码语言:txt
复制
	外部类的show方法

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

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

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

喜欢就关注博主博吧 :smile:

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 内部类
    • 基本概述
      • 语法格式
        • 成员内部类
          • 局部内部类
            • 匿名内部类
              • 静态嵌套类
                • 静态嵌套类和非静态嵌套类的区别
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档