面向对象特征一:封装性

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

 

具体修饰的结构:
外部类: 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[] 内部实 现,而对外的方法不变,我们使用者根本感觉不到它内部的修改。
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 修饰。

总结:

面向对象特征之一:封装性1. 为什么需要封装性?
理论上:-`高内聚`:类的内部数据操作细节自己完成,不允许外部干涉;-`低耦合`:仅暴露少量的方法给外部使用,尽量方便外部调用。通俗的说:把该隐藏的隐藏起来,该暴露的暴露出来。这就是封装性的设计思想。2. 如何实现数据封装?2.1 权限修饰符Java规定了4种权限修饰,分别是:private、缺省、protected、public2.2 作用我们可以使用4种权限修饰来修饰类及类的内部成员。当这些成员被调用时,体现可见性的大小。2.3 实际案例:
在题目中,我们给Animal的对象的legs属性赋值。在实际的常识中,我们知道legs不能赋值为负数的。但是如果
直接调用属性legs,是不能加入判断逻辑的。那怎么办呢?
> 将legs属性私有化(private),禁止在Animal类的外部直接调用此属性
> 提供给legs属性赋值的setLegs()方法,在此方法中加入legs赋值的判断逻辑if(legs >= 0 && legs % 2 ==0)将此方法暴露出去,使得在Animal类的外部调用此方法,对legs属性赋值。
> 提供给legs属性获取的getLegs()方法,此方法对外暴露。使得在Animal类的外部还可以调用此属性的值。2.4 4种权限具体使用
《见课件》> 类:只能使用public、缺省修饰
> 类的内部成员:可以使用4种权限修饰进行修饰。2.5 开发中4种权限使用频率的情况:比较高:public、private比较低:缺省、protected3. 封装性的体现
> 场景1:私有化(private)类的属性,提供公共(public)的get和set方法,对此属性进行获取或修改
> 场景2:将类中不需要对外暴露的方法,设置为private.
> 场景3:单例模式中构造器private的了,避免在类的外部创建实例。(放到static关键字后讲)

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/291325.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java面试题】Redis中篇(高可用:主从复制、哨兵、集群)

文章目录 高可用14.Redis如何保证高可用&#xff1f;15.Redis的主从复制&#xff1f;16.Redis主从有几种常见的拓扑结构&#xff1f;17.Redis的主从复制原理了解吗&#xff1f;18.说说主从数据同步的方式&#xff1f;19.主从复制存在的问题&#xff1f;20.Redis Sentinel(哨兵)…

基于Spring Boot 3 + Spring Security6 + JWT + Redis实现接口资源鉴权

紧接上一篇文章&#xff0c;基于Spring Boot 3 Spring Security6 JWT Redis实现接口资源鉴权 系列文章指路&#x1f449; 系列文章-基于SpringBoot3创建项目并配置常用的工具和一些常用的类 项目源码&#x1f449; /shijizhe/boot-test 文章目录 1. 修改 UserDetailsServic…

python爬虫之selenium4使用(万字讲解)

文章目录 一、前言二、selenium的介绍1、优点&#xff1a;2、缺点&#xff1a; 三、selenium环境搭建1、安装python模块2、selenium4新特性3、安装驱动WebDriver驱动选择驱动安装和测试 基础操作1、属性和方法2、单个元素定位通过id定位通过class_name定位一个元素通过xpath定位…

C语言学习-Day23-函数递归2

接上一天&#xff0c;练习2&#xff1a;编写函数不允许创建临时变量&#xff0c;求字符串的长度。 实现方式1&#xff1a; int my_strlen(char* str) { int count 0; while (*str ! \0) { count; str; } return count; } int main() { char arr[] "bit"; //[b]…

写作类AI推荐(二)

本章要介绍的写作AI如下&#xff1a; 火山写作 主要功能&#xff1a; AI智能创作&#xff1a;告诉 AI 你想写什么&#xff0c;立即生成你理想中的文章AI智能改写&#xff1a;选中段落句子&#xff0c;可提升表达、修改语气、扩写、总结、缩写等文章内容优化&#xff1a;根据全文…

Modelsim手动仿真实例

目录 1. 软件链接 2. 为什么要使用Modelsim 3. Modelsim仿真工程由几部分组成&#xff1f; 4. 上手实例 4.1. 新建文件夹 4.2. 指定目录 4.3. 新建工程 4.4. 新建设计文件&#xff08;Design Files&#xff09; 4.5. 新建测试平台文件&#xff08;Testbench Files&…

YOLOv9改进策略 :block优化 | 无需TokenMixer也能达成SOTA性能的极简ViT架构 | CVPR2023 RIFormer

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文改进内容&#xff1a; token mixer被验证能够大幅度提升性能&#xff0c;但典型的token mixer为自注意力机制&#xff0c;推理耗时长&#xff0c;计算代价大&#xff0c;而RIFormers是无需TokenMixer也能达成SOTA性能的极简ViT架构…

代下载全网资源

尊敬的用户&#xff1a; 感谢您一直以来对我们的支持和关注&#xff01;为了更好地满足用户的需求&#xff0c;我们决定在全网源码程序和软件代下载方面进行服务升级。 作为全网资源代下载服务的一部分&#xff0c;我们将提供全面的源码程序和软件代下载服务。无论是开源项目…

资源免费分享了

为了解决粉丝们在学习过程中&#xff0c;出现没有资料&#xff0c;没有书籍&#xff0c;搜索引擎搜索不精准&#xff0c;没有恰当的博文等这一类情况&#xff0c;今天&#xff0c;我将我曾经的学习资料&#xff0c;免费分享给大家&#xff01; 博主声明:此并非过度宣传&#x…

英伟达文本生成3D模型论文:Magic3D: High-Resolution Text-to-3D Content Creation解读

一、摘要 摘要&#xff1a;DreamFusion 最近展示了使用预训练的文本到图像扩散模型来优化神经辐射场 (NeRF) 的实用性&#xff0c;实现了显着的文本到 3D 合成结果。然而&#xff0c;该方法有两个固有的局限性&#xff1a;&#xff08;a&#xff09;NeRF 的优化极慢和&#xf…

Android逆向-数据修改逻辑修改视图修改

目录 0x00 相关工具及环境 0x01 APP逆向 - 数据修改 0x02 APP逆向 - 逻辑修改 0x03 APP逆向 - 视图修改 希望和各位大佬一起学习&#xff0c;如果文章内容有错请多多指正&#xff0c;谢谢&#xff01; 个人博客链接&#xff1a;CH4SER的个人BLOG – Welcome To Ch4sers B…

RocketMQ学习笔记:零拷贝

这是本人学习的总结&#xff0c;主要学习资料如下 马士兵教育rocketMq官方文档 目录 1、零拷贝技术1.1、什么是零拷贝1.2、mmap()1.3、Java中的零拷贝 1、零拷贝技术 1.1、什么是零拷贝 使用传统的IO&#xff0c;从硬盘读取数据然后发送到网络需要经过四个步骤。 通过DMA复…

css简单动画实现

html源码 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>西安工程大学</title><link …

下载安装anaconda和pytorch的详细方法,以及遇到的问题和解决办法

下载安装Anaconda 首先需要下载Anaconda&#xff0c;可以到官网Anaconda官网或者这里提供一个镜像网站去下载anaconda镜像网站 安装步骤可参考该文章&#xff1a;Anaconda安装步骤&#xff0c;本篇不再赘述 注意环境变量的配置&#xff0c;安装好Anaconda之后一定要在环境变量…

深入并广泛了解Redis常见的缓存使用问题

Redis 作为一门主流技术&#xff0c;缓存应用场景非常多&#xff0c;很多大中小厂的项目中都会使用redis作为缓存层使用。 但是Redis作为缓存&#xff0c;也会面临各种使用问题&#xff0c;比如数据一致性&#xff0c;缓存穿透&#xff0c;缓存击穿&#xff0c;缓存雪崩&#…

원클릭으로 주류 전자상거래 플랫폼 상품 상세 데이터 수집 및 접속 시연 예제 (한국어판)

클릭 한 번으로 전자상거래 플랫폼 데이터를 캡처하는 것은 일반적으로 웹 페이지에서 정보를 자동으로 추출 할 수있는 네트워크 파충류 기술과 관련됩니다.그러나 모든 형태의 데이터 수집은 해당 웹 사이트의 사용 약관 및 개인 정보 보호 정책 및 현지 법률 및 규정을 준수…

Python处理包含不可打印/显示字符的中文字符串

Python处理包含不可打印/显示字符的中文字符串 在利用Python分析一个日志文件时&#xff0c;发现python读取文件总是报错: (result, consumed) self._buffer_decode(data, self.errors, final) UnicodeDecodeError: utf-8 codec cant decode byte 0xe3 in position 210: inva…

深入探索Yarn:安装与使用指南

Yarn 是一个由 Facebook 开发的 JavaScript 包管理器&#xff0c;旨在提供更快、更可靠的包管理体验。它与 npm 类似&#xff0c;但在某些方面更加高效和可靠。本文将介绍如何安装 Yarn&#xff0c;并展示如何使用它来管理 JavaScript 项目的依赖。 1. 安装 Yarn Yarn 可以通…

香港服务器与SEO的关系(香港服务器对SEO影响大吗?)

香港服务器与 SEO 的关系是一个备受关注的话题&#xff0c;不少站长在选择了香港服务器后&#xff0c;便会疑问&#xff1a;香港服务器对SEO的影响是否显著?那么&#xff0c;在这里就跟大家聊聊两者的关系以及影响大小。 其实&#xff0c;不少站长对 SEO 的这种担忧和想法是片…

k8s系列之十七 Istio中的服务治理

删除前面配置的目的地规则 [rootk8s-master ~]# kubectl delete destinationrule details destinationrule.networking.istio.io "details" deleted [rootk8s-master ~]# kubectl delete destinationrule productpage destinationrule.networking.istio.io "pr…