一篇搞懂Java中的“四种内部类”!!!

在Java中,内部类是定义在另一个类或者其他类的方法中的类。内部类提供了一种实现细节隐藏和封装的机制,同时也可以在需要时访问外部类的成员变量和方法。Java中有四种类型的内部类:成员内部类、局部内部类、匿名内部类和静态嵌套类。下面详细介绍这些内部类:

1.成员内部类(Member Inner Class)

成员内部类是定义在另一个类的内部的普通类。它可以访问外部类的成员变量和方法,并且可以拥有自己的成员变量和方法。成员内部类的实例化需要先创建外部类的实例,然后通过外部类实例来创建成员内部类的实例。

public class Outer {
    private int outerField;
    
    public class Inner {
        public void display() {
            System.out.println("Outer Field: " + outerField);
        }
    }
}

示例:比如一个图书馆系统中的书架和书籍。

// 外部类:图书馆
public class Library {
    private String libraryName;
    
    // 构造方法
    public Library(String name) {
        this.libraryName = name;
    }
    
    // 成员内部类:书架
    public class Bookshelf {
        private int capacity;
        
        // 构造方法
        public Bookshelf(int capacity) {
            this.capacity = capacity;
        }
        
        // 内部类的方法
        public void displayBookshelfInfo() {
            System.out.println("Bookshelf capacity: " + capacity);
            System.out.println("Library name: " + libraryName);
        }
    }
    
    // 外部类的方法
    public void displayLibraryInfo() {
        System.out.println("Library name: " + libraryName);
    }
}

在这个示例中,Library 类表示一个图书馆,它有一个成员变量 libraryName 表示图书馆的名字。Library 类内部还定义了一个成员内部类 Bookshelf,表示图书馆中的书架。Bookshelf 类有一个成员变量 capacity 表示书架的容量。Bookshelf 类的构造方法中通过访问外部类的成员变量 libraryName,显示了所属图书馆的名字。同时,Library 类中还有一个方法 displayLibraryInfo(),用于显示图书馆的信息。

接下来是如何使用这些类的示例代码:

public class Main {
    public static void main(String[] args) {
        // 创建图书馆实例
        Library library = new Library("City Library");
        
        // 创建书架实例
        Library.Bookshelf bookshelf = library.new Bookshelf(100);
        
        // 调用书架的方法显示信息
        bookshelf.displayBookshelfInfo();
        
        // 调用图书馆的方法显示信息
        library.displayLibraryInfo();
    }
}

在这个示例中,我们首先创建了一个图书馆实例 library,然后通过该实例创建了一个书架实例 bookshelf。接着,调用了书架实例的 displayBookshelfInfo() 方法显示了书架的信息,以及图书馆的 displayLibraryInfo() 方法显示了图书馆的信息。

这个示例展示了成员内部类的使用,其中成员内部类 Bookshelf 可以轻松访问外部类 Library 的成员变量 libraryName,并且可以在其内部定义自己的成员变量和方法。

2.局部内部类(Local Inner Class)

局部内部类是定义在方法内部的类。它只能在该方法中被访问,通常用于解决一个方法内部的问题。与成员内部类不同,局部内部类不能被访问修饰符 privatepublicprotectedstatic 修饰。

public class Outer {
    public void display() {
        class LocalInner {
            public void print() {
                System.out.println("Local Inner");
            }
        }
        
        LocalInner inner = new LocalInner();
        inner.print();
    }
}

示例:在一个 GUI 应用程序中,当用户点击一个按钮时,可能需要执行一些特定的操作。如果这个操作是一个比较简单的逻辑,而且只在按钮的点击事件中使用,那么可以使用局部内部类来实现这个事件监听器。

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ButtonExample {

    public static void main(String[] args) {
        // 创建 JFrame 实例
        JFrame frame = new JFrame("Button Example");

        // 创建按钮
        JButton button = new JButton("Click Me");

        // 添加按钮点击事件监听器
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Button clicked!");
                JOptionPane.showMessageDialog(frame, "Button clicked!");
            }
        });

        // 将按钮添加到 JFrame 中
        frame.add(button);

        // 设置 JFrame 的大小和关闭操作
        frame.setSize(300, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

在这个示例中,我们创建了一个简单的 GUI 应用程序,其中包含一个按钮。我们通过调用 addActionListener 方法来添加一个按钮点击事件的监听器。在这个方法中,我们传入了一个匿名内部类作为监听器,该内部类实现了 ActionListener 接口,并在 actionPerformed 方法中定义了按钮点击时所需执行的逻辑。在这个例子中,当按钮被点击时,会在控制台打印消息,并弹出一个消息对话框显示相同的消息。

3.匿名内部类(Anonymous Inner Class)

匿名内部类是一种没有命名的内部类,通常用于创建一个只需使用一次的类。它通常是一个接口或者抽象类的实现,并且在创建对象时直接进行定义

  1. 没有名称:匿名类没有类名,因此它们不能被其他代码引用或重复使用。

  2. 直接创建:匿名类通常是在使用的地方直接创建的,例如作为方法参数、变量初始化或者数组初始化的一部分。

  3. 实现接口或抽象类:匿名类通常用于实现接口或抽象类,但也可以扩展类并提供自己的方法实现。

public class Outer {
    public void display() {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("Anonymous Inner");
            }
        };
        new Thread(runnable).start();
    }
}

以下是一个简单的示例,演示了如何使用匿名内部类来实现接口:

interface Greeting {
    void greet();
}

public class AnonymousInnerClassExample {

    public static void main(String[] args) {
        // 使用匿名内部类实现接口
        Greeting greeting = new Greeting() {
            @Override
            public void greet() {
                System.out.println("Hello, world!");
            }
        };

        // 调用接口方法
        greeting.greet();
    }
}

在这个示例中,我们定义了一个接口 Greeting,其中有一个抽象方法 greet。然后,在 main 方法中,我们创建了一个匿名内部类实现了这个接口,并在其中重写了 greet 方法。在匿名内部类的定义中,我们没有指定类名,而是直接创建了一个实现了 Greeting 接口的类,并重写了其中的方法。最后,我们通过接口的引用调用了 greet 方法,输出了 "Hello, world!"。

4.静态嵌套类(Static Nested Class)

静态嵌套类是定义在另一个类的内部的静态类。与其他内部类不同,静态嵌套类不持有外部类的引用,因此它不能访问外部类的非静态成员。可以直接通过外部类名访问静态嵌套类。

public class Outer {
    static class Nested {
        public void display() {
            System.out.println("Static Nested");
        }
    }
}

以下是一个静态嵌套类的示例:

public class Outer {
    private static String outerField = "Outer field";

    // 静态嵌套类
    static class Nested {
        public void display() {
            System.out.println("Nested class accessing Outer field: " + outerField);
        }
    }

    public static void main(String[] args) {
        // 创建静态嵌套类的实例
        Nested nested = new Nested();
        nested.display();
    }
}

在这个示例中,Outer 类包含了一个静态嵌套类 NestedNested 类具有一个 display 方法,该方法打印了外部类 Outer 的静态字段 outerField 的值。在 main 方法中,我们创建了 Nested 类的实例,并调用了 display 方法来访问外部类的静态字段。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

多宝气泡水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值