面向对象编程:深入理解内部类与抽象类的使用
文章目录
- 一、内部类使用:
- 1.1 成员内部类:
- 1.1.1 成员内部类的主要特点是:
- 1.2 局部内部类:
- 1.2.1 局部内部类的主要特点是:
- 1.2.2 局部内部类通常用于以下情况:
- 1.3 静态内部类:
- 1.3.1 静态内部类的主要特点是:
- 1.3.2 静态内部类通常用于以下情况:
- 1.4 匿名内部类:
- 1.4.1 实现接口:
- 1.4.2 继承类:
- 二、抽象类使用:
- 在使用抽象类时,需要注意以下几点:
内部类和抽象类是Java中面向对象编程的重要特性,它们分别用于不同的场景和目的。
一、内部类使用:
内部类是定义在另一个类内部的类,它可以直接访问外部类的成员,并且可以起到一定的封装作用。内部类有以下几种类型:
1.1 成员内部类:
定义在类的成员位置,可以访问外部类的所有成员,包括私有成员。创建成员内部类的实例时,需要先创建外部类的实例,然后通过外部类的实例来创建内部类的实例。
成员内部类是定义在类的内部,并且直接在类中的成员位置上定义的类。它和普通成员变量和成员方法类似,可以访问外部类的成员,包括私有成员。成员内部类还可以使用外部类的引用OuterClass.this来访问外部类的实例。
以下是一个成员内部类的代码案例:
public class OuterClass {private int outerValue = 10;// 成员内部类public class InnerClass {private int innerValue = 20;public void display() {System.out.println("Outer value: " + outerValue);System.out.println("Inner value: " + innerValue);}}public static void main(String[] args) {OuterClass outerObj = new OuterClass();OuterClass.InnerClass innerObj = outerObj.new InnerClass();innerObj.display();}
}
在上面的例子中,OuterClass是外部类,InnerClass是成员内部类。在main方法中,首先创建了外部类的实例outerObj,然后通过outerObj来创建内部类的实例innerObj,这就是成员内部类的使用方法。
1.1.1 成员内部类的主要特点是:
- 可以直接访问外部类的成员,包括私有成员。
- 成员内部类必须寄存在外部类的实例对象中,所以不能在没有外部类实例的情况下创建内部类的实例。
成员内部类通常用于以下情况:
- 与外部类有密切关联,需要直接访问外部类的成员。
- 需要创建多个相互独立的内部类对象,每个内部类对象都有自己的状态,但又共享外部类的数据。
需要注意的是,如果成员内部类不需要访问外部类的成员,可以将其定义为静态内部类,这样可以节省一些内存开销。静态内部类与外部类没有直接的关联,可以独立地创建对象。
1.2 局部内部类:
定义在方法或代码块内部,作用范围仅限于所在的方法或代码块内。局部内部类可以访问外部方法的参数和局部变量,但要求这些参数和变量必须是 final 或 effectively final 的。
局部内部类是定义在方法内部的类,只能在该方法内部使用,其作用域仅限于方法内部。局部内部类对于外部类以及其他方法是不可见的。
以下是一个局部内部类的代码案例:
public class OuterClass {private int outerValue = 10;public void outerMethod() {int localVar = 5;// 局部内部类class LocalInnerClass {public void display() {// 局部内部类可以访问外部类的实例变量和方法System.out.println("Outer value: " + outerValue);System.out.println("Local variable: " + localVar);}}// 创建局部内部类的实例,并调用其方法LocalInnerClass innerObj = new LocalInnerClass();innerObj.display();}public static void main(String[] args) {OuterClass outerObj = new OuterClass();outerObj.outerMethod();}
}
在上面的例子中,OuterClass是外部类,在outerMethod方法内部定义了一个局部内部类LocalInnerClass。局部内部类LocalInnerClass只能在outerMethod方法内部使用。
1.2.1 局部内部类的主要特点是:
- 定义在方法内部,只能在该方法内部使用,其作用域仅限于方法内部。
- 局部内部类可以访问外部方法的局部变量以及外部类的实例变量和方法,但局部变量必须为
final或effectively final(即不可修改)。 - 局部内部类对于外部类以及其他方法是不可见的,只能在定义它的方法内部使用。
1.2.2 局部内部类通常用于以下情况:
- 当某个类的功能只在一个特定的方法内部使用,并且不希望该类对其他方法可见时,可以将其定义为局部内部类。
- 局部内部类可以对代码进行更加细粒度的封装,提高代码的安全性和可读性。
总之,局部内部类适用于只在特定方法内部使用的情况,其作用域仅限于该方法内部。
1.3 静态内部类:
用 static 修饰的内部类,类似于一个普通的类,只是它被嵌套在其他类内部而已。静态内部类不能访问外部类的非静态成员,只能访问外部类的静态成员。
使用内部类的时候要根据实际需要选择不同的内部类类型。例如,如果内部类需要访问外部类的成员,可以使用成员内部类;如果内部类只在某个方法中使用,并且不需要访问外部类的非 final 变量,可以使用局部内部类;如果内部类不依赖外部类的实例,可以使用静态内部类。
静态内部类是定义在类的内部,并且被static关键字修饰的类。与成员内部类不同,静态内部类不依赖于外部类的实例,可以直接创建内部类的实例,而不需要先创建外部类的实例。
以下是一个静态内部类的代码案例:
public class OuterClass {private static int outerValue = 10;// 静态内部类public static class StaticInnerClass {private int innerValue = 20;public void display() {System.out.println("Outer value: " + outerValue);System.out.println("Inner value: " + innerValue);}}public static void main(String[] args) {// 创建静态内部类的实例,不需要先创建外部类的实例StaticInnerClass innerObj = new StaticInnerClass();innerObj.display();}
}
在上面的例子中,OuterClass是外部类,StaticInnerClass是静态内部类。在main方法中,直接创建了静态内部类的实例innerObj,无需先创建外部类的实例。
1.3.1 静态内部类的主要特点是:
- 可以直接创建内部类的实例,无需先创建外部类的实例。
- 静态内部类不能访问外部类的非静态成员,只能访问外部类的静态成员。
1.3.2 静态内部类通常用于以下情况:
- 当内部类不需要访问外部类的实例变量或方法时,可以将其定义为静态内部类,这样可以节省内存开销。
- 静态内部类可以作为一个独立的类来使用,可以避免与外部类的实例耦合在一起。
总之,静态内部类适用于不需要访问外部类实例成员的情况,且它与外部类实例无关。
1.4 匿名内部类:
匿名内部类是一种特殊的内部类,它没有显式地定义一个类名,而是直接在使用的地方创建一个实例。通常情况下,使用匿名内部类可以简化代码,特别是在需要创建一个只用一次的类的情况下。
匿名内部类通常用于以下情况:
1.4.1 实现接口:
当需要创建一个实现某个接口的类的实例时,可以使用匿名内部类。例如:
interface MyInterface {void doSomething();
}public class MyClass {public void methodWithInterface() {MyInterface myInterface = new MyInterface() {@Overridepublic void doSomething() {System.out.println("Doing something...");}};myInterface.doSomething();}
}
1.4.2 继承类:
当需要创建一个继承自某个类的实例时,可以使用匿名内部类。例如:
class MyBaseClass {void display() {System.out.println("Base class method.");}
}public class MyClass {public void methodWithInheritance() {MyBaseClass myBaseClass = new MyBaseClass() {@Overridevoid display() {System.out.println("Overridden method.");}};myBaseClass.display();}
}
注意,在匿名内部类中,可以重写父类或接口的方法,并且可以添加其他方法和字段。匿名内部类的作用域仅限于创建它的代码块,通常在方法中使用。
虽然匿名内部类可以简化代码,但也有一些限制和注意事项:
- 匿名内部类不能有构造方法,因为它没有类名,无法调用构造方法。
- 匿名内部类只能使用一次,不能在其他地方再次使用。
- 匿名内部类可以访问外部类的成员变量和方法,但要求这些成员变量和方法必须是 final 或 effectively final 的(Java 8 之后的版本)。
总体来说,匿名内部类是一种灵活且常用的编程技巧,适用于一些简单的类实现或临时的类需求,能够简化代码并增强代码的可读性。

二、抽象类使用:
抽象类是一种特殊的类,它不能被实例化,只能用作其他类的父类。抽象类中可以包含抽象方法和非抽象方法。抽象方法是没有具体实现的方法,必须在子类中进行重写实现。非抽象方法可以有具体实现,子类可以直接继承和使用。
使用抽象类的主要目的是为了实现代码的复用和扩展性。抽象类将一些通用的方法定义在其中,子类可以继承这些方法,并根据自己的特殊需求进行重写。抽象类还可以通过定义抽象方法来强制子类实现某些功能,这样可以保证子类都具有相同的接口,而具体实现则由子类自行决定。
在使用抽象类时,需要注意以下几点:
-
抽象类不能被实例化,只能用作其他类的父类。
-
子类必须实现抽象类中的所有抽象方法,除非子类也是抽象类。
-
抽象类可以包含非抽象方法,子类可以继承和使用这些非抽象方法。
-
一个类只能继承一个抽象类,但可以实现多个接口。
总体来说,内部类和抽象类是Java中重要的面向对象编程特性,它们都有自己的应用场景和优势。合理地使用内部类和抽象类可以提高代码的可读性、可维护性和扩展性。

相关文章:
面向对象编程:深入理解内部类与抽象类的使用
文章目录 一、内部类使用:1.1 成员内部类:1.1.1 成员内部类的主要特点是: 1.2 局部内部类:1.2.1 局部内部类的主要特点是:1.2.2 局部内部类通常用于以下情况: 1.3 静态内部类:1.3.1 静态内部类的…...
linux安装oracle
oracle安装 基于linux系统安装 Linux安装oracle12C Centos7.6 内存8GB 硬盘:50GB 可视化图形界面 yum groupinstall "GNOME Desktop" -y 可视化后续安装命令 1、软件环境包安装 yum -y install binutils compat-libcap1 compat-libstdc-33 gcc-c glib…...
切面 基于Aspect注解自动切面, 省下注解判断逻辑 handler
父文章 spring aop 切面配置_aop 切面设置.**_个人渣记录仅为自己搜索用的博客-CSDN博客 【Spring AOP】Aspect结合案例详解(一): Pointcut使用annotation 五种通知Advice注解(已附源码)_pointcut annotation_天罡gg的博客-CSDN博…...
golang,gin框架的请求参数(一)--推荐
golang,gin框架的请求参数(一) gin框架的重要性不过多的强调,重点就gin使用中的参数传递,获取进行梳理文件,满足使用需求。 获取前端请求参数的几种方法: 一、获取参数【浏览器地址获取参数】…...
ardupilot 遥控的输入控制模式
目录 本节主要记录自己整理ardupilot的遥控器的输入控制模式:正常模式、简单模式、超简单模式的理解。 1.正常模式(有头模式) 在不用简单和超简单的模式的情况下,无人机操作员操作的控制输入是对应着不断旋转着的飞行器进行操作的。如上方图所示举例,当无人机操作员进行…...
Unity UGUI的StandaloneInputModule (标准输入模块)组件的介绍及使用
Unity UGUI的StandaloneInputModule (标准输入模块)组件的介绍及使用 1. 什么是StandaloneInputModule组件? StandaloneInputModule是Unity UGUI系统中的一个标准输入模块组件,用于处理鼠标和键盘的输入事件。它可以将鼠标和键盘的输入转化为UGUI系统中…...
惠普HP Color Laser 150a开机红色感叹号闪烁不打印故障解决方法
故障描述: 惠普HP Color Laser 150a开机红色感叹号闪烁,不能打印,电脑提示C3-6140。 检测分析: 在解决C3-6140错误代码之前,我们需要先检查打印机是否连接正常。如果打印机连接不正常,也可能会出现这个错误…...
CVE-2023-1454注入分析复现
简介 JeecgBoot的代码生成器是一种可以帮助开发者快速构建企业级应用的工具,它可以通过一键生成前后端代码,无需写任何代码,让开发者更多关注业务逻辑。 影响版本 Jeecg-Boot<3.5.1 环境搭建 idea 后端源码: https://git…...
MFC使用png做背景图片
在MFC中使用png图片作为背景,你需要使用GDI库。以下是一个简单的示例: 首先,你需要在你的项目中包含GDI头文件和库。在你的stdafx.h(或者你的项目预编译头文件)中添加以下代码: #include <GdiPlus.h&g…...
Java开发的基石:JDK
Java开发的基石:JDK 前言一、引入二、JDK的发展历程三、JDK主要目录结构解析四、JDK的使用 前言 本博主将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识,有兴趣的小伙伴可以关注博主!也许一个人独行,可以走的很快&…...
使用langchain与你自己的数据对话(三):检索(Retrieval)
之前我已经完成了使用langchain与你自己的数据对话的前两篇博客,还没有阅读这两篇博客的朋友可以先阅读一下: 使用langchain与你自己的数据对话(一):文档加载与切割使用langchain与你自己的数据对话(二):向量存储与嵌入 今天我们…...
DEVICENET转ETHERNET/IP网关devicenet协议
捷米JM-EIP-DNT,你听说过吗?这是一款自主研发的ETHERNET/IP从站功能的通讯网关,它能够连接DEVICENET总线和ETHERNET/IP网络,从而解决生产管理系统中协议不同造成的数据交换互通问题。 这款产品在工业自动化领域可谓是一大利器&…...
GPT一键化身「AI助理」——自定义指令功能
最近GPT又更新了一个超实用的功能——自定义指令,启用后,你可以给GPT设置一些固定指令,让它记住或扮演某个角色,比如客服、律师、投资管理师、老师、营养师...... 这样,我们就不再需要每次都要打开新的聊天,…...
深入理解Promise
原文合集地址如下,有需要的朋友可以关注 本文地址 合集地址 什么是Promise 当谈论 Promise 时,可以将其比喻为一种承诺或契约,用于处理异步操作的结果。异步操作是指那些不会立即完成的操作,比如从服务器获取数据、读取文件、发送网络请求等等。通常情况下,这些操作需…...
【2023 年第二届钉钉杯大学生大数据挑战赛】 初赛 B:美国纽约公共自行车使用量预测分析 问题三时间序列预测Python代码分析
2023 年第二届钉钉杯大学生大数据挑战赛 初赛 B:美国纽约公共自行车使用量预测分析 问题三时间序列预测Python代码分析 相关链接 【2023 年第二届钉钉杯大学生大数据挑战赛】 初赛 B:美国纽约公共自行车使用量预测分析 问题一Python代码分析 【2023 年…...
redis-cluster 创建及监控
集群命令 cluster info:打印集群的信息。 cluster nodes:列出集群当前已知的所有节点(node)的相关信息。 cluster meet <ip> <port>:将ip和port所指定的节点添加到集群当中。 cluster addslots <slot…...
vue+ivew model框 select校验遇到的问题
iview model 点击关闭,校验没有通过也会关闭 解决办法: 第一步:自定义页脚内容 <div slot"footer"><Button type"primary" click"confirmCarryOver()">确认</Button><Button click&qu…...
mybatis_分页
目的: 减少数据处理量,提高效率 普通sql: 语法:select * from user limit startIndex,pageSize; SELECT * from user limit 3; #[0,n] mybatis_sql: 接口: //分页查询List<User> getUserByLimit(Map<…...
轻量级Firefox Send替代方案Gokapi
想不到一个域名的变动会影响这么大,访问量出现断崖式下跌。由此可见,平时的访问应该只是一些 RSS 的访问而已。 上面是 Pageviews,下面是 Uniques 今天略有回升 难怪那些大公司要花钱买域名了,不过老苏是个佛系的人,一…...
多次发请求优化为发一次请求
优化 getUserInfo 请求 要求 getUserInfo 是个通用接口,在各个模块里面都有可能使用 requestUserInfo 模拟的是请求服务端真正获取用户信息的方法 业务背景 在一个页面有 A, B, C 等多个功能模块,A, B, C 模块渲染执行顺序不可控每个模块都会调用 get…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
Qemu arm操作系统开发环境
使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...
