[TOC]
# 匿名类和内部类
* ## 内部类的范围
内部类有以下几种范围:
### 1. 成员内部类(Member Inner Class)
成员内部类是定义在外部类的成员位置上的类,它可以访问外部类的所有成员,包括私有成员,也可以被外部类以及其他类访问。
- 语法格式
~~~
public class Outer { // 定义外部类
public class Inner { // 定义内部类
}
}
~~~
### 2. 静态内部类(Static Inner Class)
静态内部类是定义在外部类的静态成员位置上的类,它不能访问外部类的非静态成员,但可以访问外部类的静态成员。
- 语法格式
```
public class OuterClass {
private static int outerStaticField;
public static class InnerClass { //定义静态内部类
}
}
```
### 3. 局部内部类(Local Inner Class)
局部内部类是定义在方法或语句块内部的类,它只能在该方法或语句块内部访问,不能被外部类和其他类访问。
- 语法格式
```
~~~
public classOuterClass {
public void method() { //定义成员方法
class InnerClass { //定义局部内部类
}
}
}
~~~
```
### 4. 匿名内部类(Anonymous Inner Class)
匿名内部类是一种没有名字的内部类,它可以用来创建一个只需要使用一次的类。匿名内部类通常用于实现某个接口或继承某个类,并重写其中的方法。
- 语法格式
```
new 接口名/类名() {
// 匿名类的成员变量和方法的定义
};
```
## 1. 主要解决了以下几个问题:
### 1.1. 简化代码。
匿名类可以避免编写完整的类来实现简单的接口或继承抽象类,简化代码量。内部类可以隐藏实现细节,保持外部类的简洁性。
```
// 简化以下代码
public interface Runnable { // 定义Runnable接口
void run();
}
// 语法格式是实例化接口或类 new 接口名/类名() {}
Runnable runnable = new Runnable() { // 使用匿名内部类实现Runnable接口
@Override
public void run() {
System.out.println("Running...");
}
};
```
需要注意的是,匿名类只能实现一个接口或继承一个类,而且它没有构造函数,因此不能在其中初始化成员变量。如果需要实现多个接口或者需要初始化成员变量,可以考虑使用具名的内部类。
*****
### 1.2. 增加封装性。
内部类可以访问外部类的私有成员,增加了封装性。局部内部类的作用域只在方法内,更加封装。
```
public class Outer { // 定义外部类
private int num = 10; // 私有成员
public class Inner { // 定义内部类
public void show() {
System.out.println(num); // 访问外部类的私有成员
}
}
}
```
*****
### 1.3. 解决多继承问题。
Java只支持单继承,通过内部类可以部分模拟多继承的效果,一个内部类可以继承一个类,而外部类可以继承另一个类。
```
public class Outer { // 定义外部类
public void show() { }
}
public class Outer2 { // 定义另一个外部类
public void display() { }
}
public class Test extends Outer { // 外部类继承Outer
public class Inner extends Outer2 { // 内部类继承Outer2
public void print() {
show(); // 调用外部类方法
display(); // 调用内部类方法
}
}
}
```
*****
### 1.4. 隐藏实现细节。
内部类的作用域仅在外部类内,可以隐藏实现细节,保持外部类的简洁。
```
public class Outer { // 定义外部类
private int num = 10; // 外部类私有成员
public class Inner { // 定义内部类
private int innerNum = 20; // 内部类私有成员
public void show() {
System.out.println(num); // 访问外部类的私有成员
System.out.println(innerNum); // 访问内部类的私有成员
}
}
public void display() { // 外部类的方法
Inner inner = new Inner(); // 实例化内部类
inner.show(); // 通过外部类方法间接调用内部类方法
}
}
```
外部类的外部无法直接访问Inner类的私有成员innerNum,实现细节被隐藏。只有通过Outer类的方法才能间接使用Inner类,这增加了封装性。
*****
### 1.5. 避免命名空间污染。
使用内部类可以避免在同一个命名空间下定义太多的类,防止命名空间污染。
```
public class Outer { // 定义外部类
public class Inner1 { // 定义内部类1
}
public class Inner2 { // 定义内部类2
}
public class Inner3 { // 定义内部类3
}
}
```
如果不使用内部类,需要在同一个命名空间下定义三个类,这会导致命名空间过于繁杂,内部类可以避免这种情况,防止命名空间污染。
*****
## 2. 匿名类示例——创建线程对象:
使用了匿名类来创建一个`Runnable`对象,重写了`run`方法,并在其中输出了一条消息。然后,我们将这个`Runnable`对象传递给`Thread`构造函数,创建了一个新的线程对象,并调用`start`方法来启动该线程。
```
public class AnonymousClassExample {
public static void main(String[] args) {
// 使用匿名类创建一个Runnable对象
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("Hello, World!");
}
};
// 使用Runnable对象创建一个线程
Thread thread = new Thread(runnable);
thread.start();
}
}
```
*****
## 3. 内部类示例——迭代器:
定义了一个成员内部类`InnerIterator`,它实现了`Iterator`接口,并重写了其中的方法。在`InnerClassExample`类中,我们定义了一个`iterator`方法,用于返回一个`InnerIterator`对象。在`main`方法中,我们使用`iterator`方法获取一个迭代器对象,并使用`while`循环输出迭代器中的元素。由于`InnerIterator`是`InnerClassExample`的成员内部类,所以它可以访问`elements`和`size`成员变量。
```
import java.util.Iterator;
public class InnerClassExample {
// 成员变量
private Object[] elements;
private int size;
// 构造方法
public InnerClassExample(Object[] elements) {
this.elements = elements;
this.size = elements.length;
}
// 获取迭代器对象的方法
public Iterator<Object> iterator() {
return new InnerIterator();
}
// 成员内部类
private class InnerIterator implements Iterator<Object> {
// 成员变量
private int index;
// 构造方法
public InnerIterator() {
this.index = 0;
}
// 判断是否还有下一个元素
@Override
public boolean hasNext() {
return index < size;
}
// 获取下一个元素
@Override
public Object next() {
if (hasNext()) {
return elements[index++];
} else {
throw new IndexOutOfBoundsException();
}
}
// 移除当前元素(不支持)
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
// 测试代码
public static void main(String[] args) {
Object[] elements = {1, 2, 3, 4, 5};
InnerClassExample example = new InnerClassExample(elements);
Iterator<Object> iterator = example.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
```
输出结果:
```
1
2
3
4
5
```
*****
- 系统设计
- 需求分析
- 概要设计
- 详细设计
- 逻辑模型设计
- 物理模型设计
- 产品设计
- 数据驱动产品设计
- 首页
- 逻辑理解
- 微服务架构的关系数据库优化
- Java基础架构
- 编程范式
- 面向对象编程【模拟现实】
- 泛型编程【参数化】
- 函数式编程
- 响应式编程【异步流】
- 并发编程【多线程】
- 面向切面编程【代码复用解耦】
- 声明式编程【注解和配置】
- 函数响应式编程
- 语法基础
- 包、接口、类、对象和切面案例代码
- Springboot按以下步骤面向切面设计程序
- 关键词
- 内部类、匿名类
- 数组、字符串、I/O
- 常用API
- 并发包
- XML
- Maven 包管理
- Pom.xml
- 技术框架
- SpringBoot
- 项目文件目录
- Vue
- Vue项目文件目录
- 远程组件
- 敏捷开发前端应用
- Pinia Store
- Vite
- Composition API
- uniapp
- 本地方法JNI
- 脚本机制
- 编译器API
- 注释
- 源码级注释
- Javadoc
- 安全
- Swing和图形化编程
- 国际化
- 精实或精益
- 精实软件数据库设计
- 精实的原理与方法
- 项目
- 零售软件
- 扩展
- 1001_docker 示例
- 1002_Docker 常用命令
- 1003_微服务
- 1004_微服务数据模型范式
- 1005_数据模型
- 1006_springCloud
- AI 流程图生成
- Wordpress_6
- Woocommerce_7
- WooCommerce常用的API和帮助函数
- WooCommerce的钩子和过滤器
- REST API
- 数据库API
- 模板系统
- 数据模型
- 1.Woo主题开发流程
- Filter
- Hook
- 可视编辑区域的函数工具
- 渲染字段函数
- 类库和框架
- TDD 通过测试来驱动开发
- 编程范式对WordPress开发
- WordPress和WooCommerce的核心代码类库组成
- 数据库修改
- 1.WP主题开发流程与时间规划
- moho
- Note 1
- 基础命令