面向对象编程(基础)9:封装性(encapsulation)
目录
9.1 为什么需要封装?
而“高内聚,低耦合”的体现之一:
9.2 何为封装性?
9.3 Java如何实现数据封装
9.4 封装性的体现
9.4.1 成员变量/属性私有化
实现步骤:
成员变量封装的好处:
9.4.2 私有化方法
9.5 练习
练习1:
练习2:
9.1 为什么需要封装?
- 我要用洗衣机,只需要按一下开关和洗涤模式就可以了。有必要了解洗衣机内部的结构吗?有必要碰电动机吗?
- 我要开车,我不需要懂离合、油门、制动等原理和维修也可以驾驶。
- 客观世界里每一个事物的内部信息都隐藏在其内部,外界无法直接操作和修改,只能通过指定的方式进行访问和修改。
随着我们系统越来越复杂,类会越来越多,那么类之间的访问边界必须把握好,面向对象的开发原则要遵循“高内聚、低耦合”。
高内聚、低耦合是软件工程中的概念,也是UNIX 操作系统设计的经典原则。
内聚,指一个模块内各个元素彼此结合的紧密程度;耦合指一个软件结构内不同模块之间互连程度的度量。内聚意味着重用和独立,耦合意味着多米诺效应牵一发动全身。
而“高内聚,低耦合”的体现之一:
高内聚:类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用,尽量方便外部调用。
9.2 何为封装性?
所谓封装,就是把客观事物封装成抽象概念的类,并且类可以把自己的数据和方法只向可信的类或者对象开放,向没必要开放的类或者对象隐藏信息。
通俗的讲,把该隐藏的隐藏起来,该暴露的暴露出来。这就是封装性的设计思想。
9.3 Java如何实现数据封装
-
实现封装就是控制类或成员的可见性范围。这就需要依赖访问控制修饰符,也称为权限修饰符来控制。
-
权限修饰符:
public、protected、缺省、private。具体访问范围如下:
| 修饰符 | 本类内部 | 本包内 | 其他包的子类 | 其他包非子类 |
|---|---|---|---|---|
| private | √ | × | × | × |
| 缺省 | √ | √ | × | × |
| protected | √ | √ | √ | × |
| public | √ | √ | √ | √ |
- 具体修饰的结构:
- 外部类:public、缺省
- 成员变量、成员方法、构造器、成员内部类:public、protected、缺省、private

9.4 封装性的体现
9.4.1 成员变量/属性私有化
概述:私有化类的成员变量,提供公共的get和set方法,对外暴露获取和修改属性的功能。
实现步骤:
① 使用 private 修饰成员变量
private 数据类型 变量名 ;
代码如下:
public class Person {private String name;private int age;private boolean marry;
}
② 提供 getXxx方法 / setXxx 方法,可以访问成员变量,代码如下:
public class Person {private String name;private int age;private boolean marry;public void setName(String n) {name = n;}public String getName() {return name;}public void setAge(int a) {age = a;}public int getAge() {return age;}public void setMarry(boolean m){marry = m;}public boolean isMarry(){return marry;}
}
③ 测试:
public class PersonTest {public static void main(String[] args) {Person p = new Person();//实例变量私有化,跨类是无法直接使用的/* p.name = "张三";p.age = 23;p.marry = true;*/p.setName("张三");System.out.println("p.name = " + p.getName());p.setAge(23);System.out.println("p.age = " + p.getAge());p.setMarry(true);System.out.println("p.marry = " + p.isMarry());}
}
成员变量封装的好处:
- 让使用者只能通过事先预定的方法来
访问数据,从而可以在该方法里面加入控制逻辑,限制对成员变量的不合理访问。还可以进行数据检查,从而有利于保证对象信息的完整性。 便于修改,提高代码的可维护性。主要说的是隐藏的部分,在内部修改了,如果其对外可以的访问方式不变的话,外部根本感觉不到它的修改。例如:Java8->Java9,String从char[]转为byte[]内部实现,而对外的方法不变,我们使用者根本感觉不到它内部的修改。
开心一笑:
A man and woman are in a computer programming lecture. The man touches the woman's breasts."Hey!" she says. "Those are private!"The man says, "But we're in the same class!"
9.4.2 私有化方法
/*** * @Description 自定义的操作数组的工具类* @author 尚硅谷-宋红康 Email:shkstart@126.com* @version**/
public class ArrayUtil {/*** * @Description 求int型数组的最大值* @author 尚硅谷-宋红康* @param arr* @return*/public int max(int[] arr) {int maxValue = arr[0];for(int i = 1;i < arr.length;i++){if(maxValue < arr[i]){maxValue = arr[i];}}return maxValue;}/*** * @Description 求int型数组的最小值* @author 尚硅谷-宋红康* @param arr* @return*/public int min(int[] arr){int minValue = arr[0];for(int i = 1;i < arr.length;i++){if(minValue > arr[i]){minValue = arr[i];}}return minValue;}/*** * @Description 求int型数组的总和* @author 尚硅谷-宋红康* @param arr* @return*/public int sum(int[] arr) {int sum = 0;for(int i = 0;i < arr.length;i++){sum += arr[i];}return sum;}/*** * @Description 求int型数组的元素的平均值* @author 尚硅谷-宋红康* @param arr* @return*/public int avg(int[] arr) {int sumValue = sum(arr);return sumValue / arr.length;}// 创建一系列重载的上述方法// public double max(double[] arr){}// public float max(float[] arr){}// public byte max(byte[] arr){}/*** * @Description 遍历数组* @author 尚硅谷-宋红康* @param arr*/public void print(int[] arr) {for(int i = 0;i < arr.length;i++){System.out.print(arr[i] + " ");}System.out.println();}/*** * @Description 复制数组arr* @author 尚硅谷-宋红康* @param arr* @return*/public int[] copy(int[] arr) {int[] arr1 = new int[arr.length];for(int i = 0;i < arr.length;i++){arr1[i] = arr[i];}return arr1;}/*** * @Description 反转数组* @author 尚硅谷-宋红康* @param arr*/public void reverse(int[] arr) {for(int i = 0,j = arr.length - 1;i < j;i++,j--){int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}/*** * @Description 数组的排序* @author 尚硅谷-宋红康* @param arr* @param desc 指明排序的方式。 ascend:升序 descend:降序*/public void sort(int[] arr,String desc) {if("ascend".equals(desc)){//if(desc.equals("ascend")){for (int i = 0; i < arr.length - 1; i++) {for (int j = 0; j < arr.length - 1 - i; j++) {if (arr[j] > arr[j + 1]) {
// int temp = arr[j];
// arr[j] = arr[j + 1];
// arr[j + 1] = temp;swap(arr,j,j+1);}}}}else if ("descend".equals(desc)){for (int i = 0; i < arr.length - 1; i++) {for (int j = 0; j < arr.length - 1 - i; j++) {if (arr[j] < arr[j + 1]) {
// int temp = arr[j];
// arr[j] = arr[j + 1];
// arr[j + 1] = temp;swap(arr,j,j+1);}}}}else{System.out.println("您输入的排序方式有误!");}}private void swap(int[] arr,int i,int j){int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}/*** * @Description 查找指定的value值在arr数组中出现的位置* @author 尚硅谷-宋红康* @param arr* @param value* @return 返回value值出现的位置 或 -1:未找到*/public int getValue(int[] arr, int value) {//方法:线性查找for(int i = 0;i < arr.length;i++){if(value == arr[i]){return i;}}return - 1;}
}
注意:
开发中,一般成员实例变量都习惯使用private修饰,再提供相应的public权限的get/set方法访问。
对于final的实例变量,不提供set()方法。(后面final关键字的时候讲)
对于static final的成员变量,习惯上使用public修饰。
9.5 练习
练习1:
创建程序:在其中定义两个类:Person和PersonTest类。定义如下:
用setAge()设置人的合法年龄(0~130),用getAge()返回人的年龄。在PersonTest类中实例化Person类的对象b,调用setAge()和getAge()方法,体会Java的封装性。

练习2:
自定义图书类。设定属性包括:书名bookName,作者author,出版社名publisher,价格price;方法包括:相应属性的get/set方法,图书信息介绍等。
相关文章:
面向对象编程(基础)9:封装性(encapsulation)
目录 9.1 为什么需要封装? 而“高内聚,低耦合”的体现之一: 9.2 何为封装性? 9.3 Java如何实现数据封装 9.4 封装性的体现 9.4.1 成员变量/属性私有化 实现步骤: 成员变量封装的好处: 9.4.2 私有化…...
fate-serving-server增加取数逻辑并源码编译
1.什么是fate-serving-server? FATE-Serving 是一个高性能、工业化的联邦学习模型服务系统,专为生产环境而设计,主要用于在线推理。 2.fate-serving-server源码编译 下载fate-serving-serving项目(GitHub - FederatedAI/FATE-Serving: A scalable, h…...
循环队列、双端队列 C和C++
队列 目录 概念 实现方式 顺序队列 循环队列 队列的数组实现 用循环链表实现队列 STL 之 queue 实现队列 STL 之 dequeue 实现双端队列 概念 队列是一种特殊的线性表,它只允许在表的前端(称为队头,front)进行删除操作…...
正则表达式(语法+例子)
文章目录一、介绍二、语法1、匹配字符2、表示数量的字符3、边界字符4、其他字符5、转义字符三、例子1、邮箱2、用逗号分隔的数字集合1,23、允许一位小数4、20yy-mm-dd日期格式5、手机号6、匹配html、xml标签一、介绍 正则表达式(Regular Expression)&am…...
Properties和IO流集合的方法
方法名说明void load(InputStream inStream)从输入字节流读取属性列表(键和元素)void load(Reader reader)从输入字符流读取属性列表(键和元素对)void store(OutputStream out,String comments)将此属性列表(键和元素对…...
python 生成器、迭代器、动态新增属性及方法
目录 一、生成器 1、生成器定义 2、生成器存在的意义 3、创建生成器方式一(生成器表达式) 4. 创建生成器方式二(生成器函数) 1. 生成器函数 2. 生成器函数的工作原理 5. 总结 1. 什么是生成器 2. 生成器特点 二、迭代器…...
Java处理JSON
Java处理json有很多种方法,在这里总结一下。 1 Jackson Spring MVC 默认采用Jackson解析Json,出于最小依赖的考虑,也许Json解析第一选择就应该是Jackson。 1.1 引入的包 Jackson核心模块由三部分组成:jackson-core、jackson-a…...
58-Map和Set练习-LeetCode692前k个高频单词
题目 给定一个单词列表 words 和一个整数 k ,返回前 k 个出现次数最多的单词。 返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序 排序。 示例 1: 输入: words ["i", "love", …...
线程生命周期及五种状态
文章目录一、线程生命周期及五种状态1、New(初始化状态)2、Runnable(就绪状态)3、Running(运行状态)4、Blocked(阻塞状态)5、Terminated(终止状态)二、线程基本方法1、线程等待(wait)2、线程睡眠(sleep)3、…...
OBCP第八章 OB运维、监控与异常处理-灾难恢复
灾难恢复是指当数据库中的数据在被有意或无意破坏后复原数据库所需要执行的活动 回收站:回收站在原理上说就是一个数据字典表,放置用户删除的数据库对象信息。用户删除的东西被放入回收站后,其实仍然占据着物理空间,除非您手动进…...
亚马逊云科技Serverless Data:数字经济下的创新动能
Serverless时代已经到来!企业的技术架构,总是伴随着不断增长的数据与日趋复杂的业务持续演进。如何通过构建更易用的技术架构来聚焦在业务本身,而不必在底层基础设施的管理上投入过多的精力,是数据驱动型企业需要思考的重要议题。…...
【Ruby学习笔记】15.Ruby 异常
Ruby 异常 异常和执行总是被联系在一起。如果您打开一个不存在的文件,且没有恰当地处理这种情况,那么您的程序则被认为是低质量的。 如果异常发生,则程序停止。异常用于处理各种类型的错误,这些错误可能在程序执行期间发生&…...
聊聊MySQL主从延迟
文章目录 MySQL 的高可用是如何实现的呢?二、什么是主备延迟?三、主备延迟常见原因1、备库机器配置差2、备库干私活3、大事务四、主库不可用,主备切换有哪些策略?1、可靠优先2、可用优先实验一实验二3、结论MySQL 的高可用是如何实现的呢? 高可用性(high availability,缩…...
【C++从0到1】19、C++中多条件的if语句
C从0到1全系列教程 1、多条件的if语句 语法: if (表达式一) { // 表达式一为真时执行的语句。 } else if (表达式二) {// 表达式二为真时执行的语句。 } else if (表达式三) {// 表达式三为真时执行的语句。 } …… else if (表达式n) {// 表达式n为真时执行的语句。…...
【多微电网】计及碳排放的基于交替方向乘子法(ADMM)的多微网电能交互分布式运行策略研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
Linux(centos7)安装防火墙firewalld及开放端口相关命令
安装firewalld 防火墙命令: yum install firewalld 安装完成,查看防火墙状态为 not running,即未运行,输入命令开启: 添加开放端口: 防火墙相关命令: 查看防火墙状态 systemctl status firewa…...
Linux部署.Net Core Web项目
本文主要记录我在Linux(Ubuntu)上部署.net core 的操作记录,也便于以后部署。 如对您有所帮助,不胜荣幸~ 文章目录前言一、准备工作1. 版本信息2. windows端web项目二、操作步骤1. Linux 配置 .net 运行环境1.1 查看最新 .net 运行环境的下载路径1.2 安装…...
【C++】STL之stack、queue的使用和模拟实现+优先级队列(附仿函数)+容器适配器详解
之前的一段时间,我们共同学习了STL中一些容器,如string、vector和list等等。本章我们将步入新阶段的学习——容器适配器。本章将详解stack、queue的使用和模拟实现优先级队列(附仿函数)容器适配器等。 目录 (一&…...
第⑦讲:Ceph集群RGW对象存储核心概念及部署使用
文章目录1.RadosGW对象存储核心概念1.1.什么是RadosGW对象存储1.2.RGW对象存储架构1.3.RGW对象存储的特点1.4.对象存储中Bucket的特性1.4.不同接口类型的对象存储访问对比2.在集群中部署RadosGW对象存储组件2.1.部署RGW组件2.2.集群中部署完RGW组件后观察集群的信息状态2.3.修改…...
从异步到promise
一,背景 1.1,js的单线程 这一切,要从js诞生之初说起,因为js是单线程的语言。 js单线程原因:作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程&…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
ArcPy扩展模块的使用(3)
管理工程项目 arcpy.mp模块允许用户管理布局、地图、报表、文件夹连接、视图等工程项目。例如,可以更新、修复或替换图层数据源,修改图层的符号系统,甚至自动在线执行共享要托管在组织中的工程项。 以下代码展示了如何更新图层的数据源&…...
JavaScript 标签加载
目录 JavaScript 标签加载script 标签的 async 和 defer 属性,分别代表什么,有什么区别1. 普通 script 标签2. async 属性3. defer 属性4. type"module"5. 各种加载方式的对比6. 使用建议 JavaScript 标签加载 script 标签的 async 和 defer …...
盲盒一番赏小程序:引领盲盒新潮流
在盲盒市场日益火爆的今天,如何才能在众多盲盒产品中脱颖而出?盲盒一番赏小程序给出了答案,它以创新的玩法和优质的服务,引领着盲盒新潮流。 一番赏小程序的最大特色在于其独特的赏品分级制度。赏品分为多个等级,从普…...
MATLAB生成大规模无线通信网络拓扑(任意节点数量)
功能: 生成任意节点数量的网络拓扑,符合现实世界节点空间分布和连接规律 效果: 30节点: 100节点: 500节点: 程序: %创建时间:2025年6月8日 %zhouzhichao %自然生长出n节点的网络% …...
