初探Java内部类的使用

初探Java内部类的使用

什么是内部类

Java中的内部类,指的是定义在另一个类中的类。内部类被认为是一个单独的实体,能够访问其外部类的所有成员。因此,内部类拥有更多的访问权限及更加灵活的控制能力。

一个内部类可以具有任意的访问权限及修饰符,这其中最为关键的是private,即表示该内部类仅仅只能被它的外部类所访问。不同的内部类也拥有不同的访问权限及特殊性质,下面我们一一进行讲解与说明。

内部类的特点

  1. 应当了解的是,每一个内部类都能够独立地继承自一个(接口的)实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。

  2. 内部是外部的一个成员,所以访问权限是一样的。同样的,内部类也能访问外部类的所有数据,包括私有(private)数据。

  3. 外部不能直接访问内部类的成员数据,需要通过内部类对象来访问。

  4. 内部类可以将多个相关类组织在一起,方便编写和维护代码。

非静态内部类

非静态内部类也称为成员内部类,它是在外部类中定义的一个普通的内部类,没有使用static关键字修饰。非静态内部类能够访问外部类的所有成员变量和方法,甚至包括private成员变量和方法。

示例1

以一个学生类(Student)和一个班级类(Class)为例,学生可以加入班级,但是班级中又有一些方法只有学生才能调用。

public class Class {
    private Strint name;
    private List<Student> students = new ArrayList<>();

    public Class(String name) {
        this.name = name;
    }

    public void addStudent(Student student) {
        students.add(student);
    }

    public Student getStudent(String studentName) {
        for (Student student:students) {
            if(student.getName().equals(studentName)) {
                return student;
            }
        }
        return null;
    }

    //内部类,用来实现的辅助功能
    private class Helper {
        public void printClass() {
            System.out.println("班级名称:" + name);
        }
    }

    //公共的统一接口方法
    public void printClass() {
        Helper helper = new Helper();
        helper.printClass();
        for (Student student : students) {
            System.out.println(student.getName());
        }
    }

    public class Student {
        private String name;

        public Student(String name) {
            this.name = name;
        }

        //这个函数只有学生自己能够调用
        public void printClass() {
            System.out.println("我所在班级名称:" + Class.this.name);
        }

        public String getName() {
            return name;
        }
    }
}

在这个例子中,我们创建了一个班级类Class,以及一个Class.Student内部类,它表示一个学生。之后我们又增加了一个Class.Helper内部类,用来实现班级打印的辅助功能。我们完整地讲解了如何在内部类中访问外部类的成员变量和方法,并强调了Class.Student内部类中基本方法和Class.Helper内部类的链式操作。

静态内部类

静态内部类和非静态内部类不同,它是在外部类中定义的静态内部类,使用static关键字进行修饰。由于静态方法不能访问非静态域,所以静态内部类不能访问外部类的非静态成员对象方法。但是,相对的,静态内部类只能够访问外部类的静态成员变量或方法。

注意,通常静态内部类与外部类之间不存在继承关系,它们是通过独立的类相互关联。

示例2

通过示例2,了解如何创建一个内部类

public class StaticInnerClassDemo {
    private static String outerClassField = "outerClassField";
    private String instanceField = "instanceField";

    private static void outerClassMethod() {
        System.out.println("outerClassMethod");
    }

    private void instanceMethod() {
        System.out.println("instanceMethod");
    }

    public static class StaticInnerClass {
        public void innerClassMethod() {
            System.out.println("innerClassMethod");
            System.out.println(outerClassField);
            outerClassMethod();
        }
    }
}

本地内部类

局部内部类,也叫本地内部类,定义在方法中,只能方法中访问,一般的,定义在方法中的类,我们称之为局部变量,那么定义在局部变量中的类就叫做本地内部类了。本地内部类只能在该方法被调用的时候才能够使用。本地内部类可以访问该方法中的final类型的参数或者本地变量,这个操作非常类似于闭包。

注意,如果要在该方法中访问的本地变量非final类型,那么它的值将无法传递给本地内部类中的final属性,从而将无法进行访问。

示例3

通过示例3,了解桌面端Java实现Swing的一个经典范例:Button程序中嵌入ActionLister监听器,中间实现一个局部内部类。

public class ButtonTest {
    public static void main(String[] agrs) {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        frame.add(panel);

        JButton button = new JButton("OK");
        panel.add(button);

        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showConfirmDialog(null, "Hello World", "title", JOptionPane.YES_NO_OPTION);
            }
        });

        frame.pack();
        frame.setVisible(true);
    }
}

内部类的使用

内部类在访问外部类中的成员变量和方法时非常方便,也可以将多个相关类组织在一起,实现更好的结构化代码编写。不过,使用内部类的时候要注意内部类访问外部类的限制,还有就是在使用非静态内部类和本地内部类的时候,一定要记得建立先外部类的对象,然后再建立内部类的对象,否则程序在运行时会发生错误。我们通过示例说明,来帮助大家更好地掌握内部类的使用。

示例:

public class Outer {
    private String s;

    // 构造器
    public Outer(String s) {
        this.s = s;
    }

    // 内部类
    public class Inner {
        public void printS() {
            System.out.println(s);
        }
    }
}

public class Test {
    public static void main(String[] args) {
        Outer o = new Outer("Hello World");
        Outer.Inner oi = o.new Inner();
        oi.printS();
    }
}

在例子中,我们创建了一个外部类Outer以及它的内部类Inner,它们之间相互关联,通过实例化Outer类的实例对象,建立对于Inner内部类对象的引用,从而实现对Inner类的访问。需要重点注意的是,先外部类的对象,后内部类的对象,这是内部类使用时的标配,需谨记。同时也需要注意到的是,对于内部类的访问,也有其明确定义的规范,不能跑偏。

总结

Java语言中的内部类是一种非常重要的语言特性,可以方便的访问外部类中的所有成员数据,并且能够将多个相关类组织在一起,实现更好的结构化代码编写。在实际开发中,我们需要灵活的使用内部类,选择合适的内部类实现方式,以实现更加高效和易读的代码编写。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:初探Java内部类的使用 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • 解决java文件流处理异常 mark/reset not supported问题

    Java文件流处理异常“mark/reset not supported”的解决方法如下: 问题描述 在使用Java文件流处理时,有时候会出现“mark/reset not supported”的异常信息。这个异常的原因是因为Java文件流默认不支持mark和reset方法。这两个方法是InputStream的一部分,但并不是所有的InputStream实现…

    Java 2023年5月27日
    00
  • spring如何实现依赖注入DI(spring-test方式)

    Spring实现依赖注入DI(spring-test方式) Spring是一个基于Java的开源框架,已经成为现代Java开发的事实标准,是构建企业级应用程序的首选框架之一。Spring实现了依赖注入(DI),使得开发者可以更加方便地编写可测试可维护的代码。本篇文章将详细介绍Spring如何实现依赖注入DI,以及如何使用spring-test进行测试。 DI…

    Java 2023年5月19日
    00
  • Java限流实现的几种方法详解

    Java限流实现的几种方法详解 什么是限流 限流是指在高并发的情况下,为了保护应用系统的稳定性和可用性,通过对请求进行控制和限制,使得系统在单位时间内能够处理的请求数量达到峰值或者控制在峰值以下,以避免系统崩溃或者服务不可用。 为什么需要限流 在高并发的场景中,一旦请求量超出系统的承受范围,就会导致服务的不可用,或者服务响应变慢,最终影响到用户体验。此时,通…

    Java 2023年5月19日
    00
  • Java实现的mysql事务处理操作示例

    当我们想要在Java应用程序中使用MySQL数据库时,需要处理事务操作。这里,我将向您展示如何使用Java和JDBC来处理MySQL事务。下面是一个完整攻略: 1. 添加MySQL JDBC驱动 在使用MySQL数据库之前,我们需要在Java项目中添加相应的MySQL JDBC驱动。您可以从官方网站下载最新的JDBC驱动程序,也可以使用第三方依赖管理工具,如…

    Java 2023年5月19日
    00
  • 详解JNI到底是什么

    JNI全称为Java Native Interface,是Java语言与其他编程语言(如C、C++)进行交互的接口。JNI可以使Java程序通过调用本地(C、C++)编写的程序,实现高效的、与操作系统直接交互的功能。下面详细讲解JNI到底是什么,让你对JNI有更深刻的理解和认识。 什么是JNI? JNI是Java的一部分,是Java语言本身提供的一个开发工具…

    Java 2023年5月26日
    00
  • 如何使用MyBatis框架实现增删改查(CRUD)操作

    使用MyBatis框架实现增删改查(CRUD)操作是非常简单的,在下面的攻略中,我将展示如何使用MyBatis框架来完成这些操作。 准备工作 在开始使用MyBatis框架之前,你需要完成以下准备工作: 确定数据库连接信息,包括数据库名称、用户名和密码等。 安装MyBatis框架和相关依赖。 创建数据库表 首先我们需要创建一张用于存储数据的表,例如创建一个名为…

    Java 2023年5月20日
    00
  • Java SpringBoot项目如何优雅的实现操作日志记录

    针对Java SpringBoot项目实现操作日志记录的攻略,主要包括以下几个方面: 一、使用AOP切面编程实现日志记录 AOP切面编程是Java Spring框架中的重要特性之一,通过定义切面和切入点,可以在程序中对方法进行增强,实现各个方面的统一处理。在日志记录方面,可以通过定义切面,对所有需要记录日志的方法进行切入。 创建自定义注解 首先,我们需要定义…

    Java 2023年5月19日
    00
  • 如何选择合适的Java垃圾收集器?

    首先,我们需要了解几种Java垃圾收集器的工作原理和特点,以作为选择的依据。通常我们会考虑以下几个方面: 垃圾回收机制:垃圾回收的机制是选择垃圾收集器的一个关键考虑因素。 内存模型:垃圾收集器通常会根据内存模型的特点来选择合适的算法。 吞吐量和延迟:吞吐量和延迟是垃圾收集器选择的主要考虑因素。 碎片整理能力:这是垃圾收集器的一个关键特点。碎片整理能力越强,程…

    Java 2023年5月11日
    00
合作推广
合作推广
分享本页
返回顶部