面向对象编程(基础)9:封装性(encapsulation)

news/2024/11/28 9:35:58/

目录

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如何实现数据封装

  • 实现封装就是控制类或成员的可见性范围。这就需要依赖访问控制修饰符,也称为权限修饰符来控制。

  • 权限修饰符:publicprotected缺省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方法,图书信息介绍等。


http://www.ppmy.cn/news/39270.html

相关文章

IEArch-卷积神经网络

一、感受 ​ 这次作业的神经网络是比上一次作业复杂的&#xff0c;上一次作业是“多层感知机&#xff08;MLP&#xff09;”&#xff0c;这一次的作业是“卷积神经网络&#xff08;CNN&#xff09;”。运算从原来的矩阵乘法变成了卷积&#xff0c;网络结构也更加复杂&#xff…

Pod生命周期简洁版

Pod 的生命周期 Pod 的生命周期 官方文档链接 Pod的status字段是一个PodStatus的对象&#xff0c;PodStatus中有一个phase字段。无论是手动创建还是通过Deployment等控制器创建&#xff0c;Pod对象总是应该处于其生命进程中以下几个阶段&#xff08;phase&#xff09;之一。 …

koa开发实践2:为koa项目添加路由模块

nodeJS server-side-developkoa开发实践2&#xff1a;为koa项目添加路由模块上一节&#xff1a;《 koa开发实践2&#xff1a;为koa项目添加路由模块 》| 下一节&#xff1a;《 koa开发实践3&#xff1a;在koa项目中使用 swagger 文档 》作者&#xff1a; 李俊才&#xff1a;…

Android 事件分发源码解析(基于API31)

文章目录事件分发从何说起&#xff1f;以一个什么框架去学习&#xff1f;重点关于事件事件是由一系列事件组成的事件流。这里先总览一下这三个方法都要做些什么&#xff1a;View的事件分发先明确一下框架中提到的问题&#xff1a;View 的事件分发源码分析总结ViewGroup的事件分…

@Lookup与@Bean@Scope获取原型实例,谁更胜一筹

那必然是 Lookup 呀 &#x1f6fc;他是谁 | 运行时查找 bean示例 | 谁更好呢作用 | 妙用多多他是谁 | 运行时查找 bean Lookup是Spring框架的一部分&#xff0c;它允许在运行时动态查找bean。使用Lookup注解的方法必须返回一个bean&#xff0c;它将在每次调用该方法时创建一个…

redis实战---乐观锁与悲观锁

乐观锁和悲观锁故事背景概念乐观锁悲观锁乐观锁示例悲观锁示例总结提升故事背景 概念 Redis是一个内存中的键值存储系统&#xff0c;支持多种数据结构&#xff0c;如字符串、哈希、列表等。Redis提供了两种锁机制&#xff0c;即乐观锁和悲观锁。 乐观锁 乐观锁是一种乐观的…

Properties

Properties概述&#xff1a; 是一个Map体系的集合类 Properties可以保存到流中或从流中加载 练习&#xff1a;Properties作为Map集合的使用 package com.aynu13;//练习&#xff1a;Properties作为Map集合的使用import java.util.Properties; import java.util.Set;public cla…

3年外包离奇被裁,痛定思痛24K上岸字节跳动....

三年前&#xff0c;我刚刚从大学毕业&#xff0c;来到了一家外包公司工作。这份工作对于我来说是个好的起点&#xff0c;因为它让我接触到了真正的企业项目和实际的开发流程。但是&#xff0c;随着时间的流逝&#xff0c;我发现这份工作并没有给我带来足够的成长和挑战。 三年…