面向对象编程:深入理解内部类与抽象类的使用
文章目录
- 一、内部类使用:
- 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…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...
leetcode73-矩阵置零
leetcode 73 思路 记录 0 元素的位置:遍历整个矩阵,找出所有值为 0 的元素,并将它们的坐标记录在数组zeroPosition中置零操作:遍历记录的所有 0 元素位置,将每个位置对应的行和列的所有元素置为 0 具体步骤 初始化…...
字符串哈希+KMP
P10468 兔子与兔子 #include<bits/stdc.h> using namespace std; typedef unsigned long long ull; const int N 1000010; ull a[N], pw[N]; int n; ull gethash(int l, int r){return a[r] - a[l - 1] * pw[r - l 1]; } signed main(){ios::sync_with_stdio(false), …...
