当前位置: 首页 > article >正文

111 - Lecture 6 - Objects and Classes

Motivation

动机

1.基本数据类型的局限性:
• int、double等基本数据类型只能存储单一的值,功能非常有限,只能回答“你存储的是什么值?”这一问题。

2.数组的局限性:
• 数组是一种线性数据结构,存储在连续的(contiguous)内存位置,能够快速访问和操作数据,但只能存储同一种数据类型。
• 现实中的数据(例如学生记录、银行账户、地址簿)通常由不同类型(homogeneous/same/single)的数据组成,无法用简单的数组表示。
3.现实世界中的数据:
• 现实中的数据由不同类型的变量组成。例如:
• 学生记录:学号、姓名、专业、入学年份等。
• 银行账户:账号、账户名、货币类型、余额等。
• 通讯录:姓名、地址、联系电话等。
在数据库应用中,这些结构称为记录(Records)

Example: Temperature

温度转换的例子

•	问题描述:
•	编写一个程序,输入一个温度值(华氏Fahrenheit、摄氏Celsius或开尔文Kelvin),并显示该温度在其他两个单位的转换结果。
•	使用 double degree = 0.0; 和 char scale = 'F'; 来存储温度和温标(scale)。
•	使用函数 f(degree, scale); 来转换温度,并用 System.out.println(degree + " " + scale); 来显示温度。

改进建议:
• 如何将温度和温标组合成一个对象?这个对象是否能够自动在不同温标之间转换,并能自己打印结果?

Object Oriented Solution

面向对象的解决方案

	Java中的类和对象:
(类和对象是面向对象编程(OOP)的基本概念,用来表示现实世界中的概念和实体(entities)。)
•	类是对象的蓝图或模型,定义了对象的属性和行为。

•	通过类可以构建“智能对象”,这些对象不仅可以存储数据,还可以回答各种问题并执行操作,例如:
•	你的温度是多少?
•	你的华氏温度是多少?
•	打印你的开尔文温度。

Objects

什么是对象?

•	对象:是一种数据抽象(data abstraction),包含两部分:
1.	内部表示(internal representation):通过数据成员(又称属性properties/attributes)来存储对象的状态。
2.	接口(interface):通过方法(又称过程或函数)与其他对象交互,定义对象的行为并隐藏实现细节(hide implementations)。

Example

现实生活中的例子

•	电梯:
•	属性:长度、宽度、高度、最大容量、当前楼层。
•	功能:移动到不同楼层、添加人、移除人。

•	学生:
•	属性:学号、姓名、出生日期、学习项目、学习年限、学习的模块。
•	功能:添加新模块、移除模块、更新学习进度(study progress update)。

•	打印队列(queue):
•	属性:打印作业列表。
•	功能:添加新的打印作业、移除已完成的打印作业。

•	煎饼堆(stack of pancakes):
•	属性:每个煎饼可以表示为一个字符串。
•	功能:添加(append)煎饼到堆的顶部,移除堆顶的煎饼。

Object oriented programming

面向对象编程(OOP)的优势

• 数据封装(Bundle data):将数据和操作封装在对象中,通过定义良好的接口与外界交互。
• 模块化开发(Divide-and-conquer):可以单独实现和测试每个类的行为,降低系统复杂性。
• 代码复用:类的定义可以被重复使用,Java模块可以通过定义新类来扩展功能。
• 继承(inheritance):子类可以重写或扩展父类的行为,例如“车辆”类的子类可以是“汽车”、“公交车”、“自行车”。

Declaring and Defining a class

类的声明与定义

•	类的定义:类似于定义一个函数,告诉Java虚拟机(JVM)这个类包含的数据成员和操作。
•	数据成员:定义对象需要存储的数据。
•	成员函数:定义对象的功能(如方法)。
•	实例化对象(instances of objects):类似于调用函数时传递不同的参数,通过类创建对象实例。

Example: a point in a coordinate type system

类定义示例:坐标系统中的点

•	类声明:public class Point {} 用来声明一个名为 Point 的类。
•	数据成员(properties):private double x; private double y; 用来存储点的坐标。
•	成员函数(method/capability):例如计算两点之间的距离,可以使用 public double distance(Point p) 方法。

Each class goes in its own file, where name of file must match name of class
▶ E.g., Point class is contained in file “Point.java”

请添加图片描述

Classes and instances

实例化(Instantiation)
实例化意味着在程序中创建新的对象实例。

•	例如:Point pt = new Point(); 或 Point pt; pt = new Point();。
•	这表示 pt 是一个通过 Point 类的蓝图创建的特定实例。

	内存结构:
•	在开始时,Point 类只是内存中的一个类定义。
•	当创建了 pt 这个实例时,一个“对象”就从内存中创建出来。

	例如:
•	创建另一个对象:Point ptB = new Point();
•	这些都是存储在内存中的对象。

如何设置 x 和 y 的值?

•	默认情况下,创建的 Point 对象的 x 和 y 均为 0。接下来需要讨论如何设置这些私有属性的值。

设置/更改私有属性的值

几种修改私有属性的方式

1.	修改属性修饰符为 public:
•	这样做会允许用户直接访问或修改属性值(没有任何控制),因此 不推荐 这种做法。

2.	定义方法(Defines methode) 来获取和设置属性值:
•	通过getter和setter方法提供受控访问,允许用户间接访问或修改私有属性。

3.	定义构造函数(constructor) 来在对象创建时为数据成员赋值:
•	构造函数可以在创建对象时自动设置属性的初始值。

• 重点讨论第二种和第三种方式,即通过方法和构造函数来控制属性的访问和修改。

Constructor

构造函数

•	构造函数:是一种特殊的成员函数,其名称与类名相同,用于初始化对象的数据成员。

当一个对象被声明时,构造函数会自动被调用,用于初始化(initializes)对象的数据成员,执行初始化任务

  1. 默认构造函数(Default-Value Constrctor/default constructors):不接受任何参数,创建对象时赋予默认值(default values)。

请添加图片描述

To create new instances of a point using default constructor:

Point pt = new Point();

You can only have ONE default-value constructor

  1. 显式值构造函数(Explicit-Value Constructor):接受参数,用于设置对象的初始值。

请添加图片描述

To create new instance of a point with explicit-value constructor:

Point pt = new Point(3,4);

You can have as many explicit-value constructors as are necessary

Remark

构造函数的必要性

•	每个类必须有一个构造函数(constructor):每个类在创建对象时都需要一个构造函数,用于初始化对象的属性。
•	自动调用(automatically called):构造函数在对象创建时会自动调用,因此它是对象“出生”时必须执行的操作。
•	构造函数没有返回类型:构造函数不允许有返回类型,甚至不能写 void。构造函数的唯一功能是初始化对象。

默认构造函数的生成

•	如果程序员没有显式定义任何构造函数,编译器将自动生成(generated)一个“默认空构造函数(default empty constrctor)”。这个构造函数不会执行任何操作,但它可以确保对象的正确创建。

示例:

public Point() {
}
•	这个默认构造函数允许创建 Point 对象,而不设置任何初始值。

Get/Set data member values with methods

数据成员的获取与设置

检查器函数(Inspector functions)

Getter函数

•	概念:在Java中,检查器函数通常称为getter函数。它们允许程序员读取类的数据成员,但不允许修改它们。
•	作用:getter函数的主要功能是读取私有属性的值,而不允许直接修改。
•	代码示例:获取 Point 类中的 x 和 y 值的getter函数如下:
public double getX() {
  return x;
}

public double getY() {
  return y;
}
•	命名约定:在Java中,getter函数的名称通常以 get 开头,后跟属性名称。例如,getX() 用于获取 x 值,这就是为什么这些函数被称为getter函数。

修改器函数(Mutator functions)

Setter函数

•	概念:在Java中,修改器函数通常称为setter函数。它们允许程序员修改类的数据成员的值。
•	作用:setter函数用于设置或更新私有属性的值。
•	代码示例:设置 Point 类中的 x 和 y 值的setter函数如下:
public void setX(double newX) {
  x = newX;
}

public void setY(double newY) {
  y = newY;
}
•	命名约定:在Java中,setter函数的名称通常以 set 开头,后跟属性名称。例如,setX() 用于设置 x 值,这就是为什么这些函数被称为setter函数。
•	改进代码可读性:图片中提到,我们每次为setter提供新变量名(如newX)时,可以通过优化代码来提高可读性。

this 对象实例变量

this 关键字的概念

•	定义:this 是“当前实例”的缩写,表示类的当前实例,当前实例可以调用它自身的方法。
•	作用:this 关键字允许一个实例(如 pt)在它自己上调用自己的方法(on itself)。
•	使用场景:我们可以使用 this 来引用或调用类中已经存在的成员变量或方法。通过 this,可以避免变量名冲突。

代码示例

•	以下是使用 this 关键字的setter函数:
public void setX(double x) {
  this.x = x;
}

public void setY(double y) {
  this.y = y;
}
•	在这些代码中,this.x 表示当前对象的 x 值,x 是传入的参数。这避免了参数名与成员变量名相同导致的混淆。
•	this 的应用范围:this 可以在类的所有方法中使用,包括构造函数。
TopHat Question

关于 this.getX(); 在 Point 类中的作用
1.其他对象不能调用 getX() 方法

•	分析:这个说法是错误的。getX() 是一个公共(public)的getter方法,其他对象是可以调用它的。只要该方法的访问修饰符为 public,其他类的对象就可以访问它。

2.当前 Point 类的实例正在调用另一个 Point 实例的 getX() 方法

•	分析:这个说法也是错误的。this.getX(); 只在当前对象的上下文中使用,表示调用当前对象本身的 getX() 方法,而不是调用其他对象的方法。

3.当前 Point 类的实例调用了它自身的 getX() 方法

•	分析:这是正确的。this.getX(); 的作用是让当前的 Point 实例调用它自身的 getX() 方法。这是 this 关键字的典型用途,用于引用当前实例的属性或方法。

4.this.getX(); 的调用不会出现在 Point 类的其他地方

•	分析:这个说法也是错误的。this.getX(); 可能会出现在 Point 类的多个方法中,特别是在需要获取当前对象的 x 值时。没有任何限制规定 this.getX(); 只能出现在一个地方。

Interacting with other objects

对象之间的交互

•	使用方法与其他对象交互:一个对象的方法可以接受其他对象作为输入并进行操作。例如,计算两点之间的距离:

public double distance(Point p) {
return Math.sqrt(Math.pow(x - p.x, 2) + Math.pow(y - p.y, 2));
}
请添加图片描述

面向对象程序设计的基本概念

定义:
• 面向对象程序设计是一种通过定义和实现对象类(Object Classes)来开发程序的方法。
• 程序由对象组成,这些对象通过彼此之间的交互来完成特定任务。

核心概念:
1. 对象类的定义和实现:

• 对象类可以相互关联并交互。
• 例如,一个 Polygon(多边形)类的对象可以通过调用 Pen(画笔)类的对象的方法,在屏幕上绘制多边形。

  1. 程序的作用:
•	创建、管理和销毁对象:
	程序的核心在于管理对象的生命周期。
	Java 中的自动内存管理: 对象的销毁由 JVM 的垃圾回收器(Garbage Collector)自动完成。

•	调用对象方法(方法调用):
	通过对象的方法,解决问题或完成任务。

面向对象程序设计

•	高层设计(High-Level Design):
1.	分析并确定解决问题所需的数据和操作。
2.	定义对象类。
3.	设计程序结构和顶层算法。
•	低层设计(Low-Level Design):专注于每个对象类的内部实现细节和算法。

数据封装

•	封装性:
•	将数据和操作数据的方法绑定在一起,同时隐藏实现细节。
•	用户只能通过特定的接口(方法)访问数据。

访问修饰符:public、private 和 protected 用来控制类的成员对外的可见性。
• Getter 方法: 用于安全地读取私有数据。
• Setter 方法: 用于安全地更新私有数据,可以添加校验逻辑。
信息隐藏:
• 只暴露必要的接口,其余部分保持隐藏,避免外部依赖内部实现。

总结

•	类:类是对象的蓝图,定义了对象的属性和行为。
•	实例:实例是类的具体化,可以调用类中的方法。
•	方法声明与定义:方法是类的功能实现,包含访问修饰符、返回类型、方法名和参数列表。
•	面向对象程序设计:通过数据封装和信息隐藏来构建复杂系统,减少系统复杂度。

http://www.kler.cn/a/468049.html

相关文章:

  • 25/1/6 算法笔记<强化学习> 初玩V-REP
  • 云架构Web端的工业MES系统设计之区分工业过程
  • 【SpringBoot】当 @PathVariable 遇到 /,如何处理
  • 电脑里msvcr120.dll文件丢失怎样修复?
  • 使用SSH建立内网穿透,能够访问内网的web服务器
  • 设计形成从业务特点到设计模式的关联
  • 《深度学习梯度消失问题:原因与解决之道》
  • 第9章 子程序与函数调用
  • 【LLM】概念解析 - Tensorflow/Transformer/PyTorch
  • MQTT学习笔记
  • php容器设计模式
  • 050_小驰私房菜_MTK Camera debug, data rate 、mipi_pixel_rate 确认
  • 基于图的去中心化社会推荐过滤器
  • ip属地的信息准确吗?ip归属地不准确怎么办
  • 前端实现大文件上传(文件分片、文件hash、并发上传、断点续传、进度监控和错误处理,含nodejs)
  • 抖音评论区的IP属地可以关吗?详细解答
  • 安卓应用4字节不对齐导致so加载失败
  • javaEE-文件内容的读写
  • MySQL--》快速提高查询效率:SQL语句优化技巧与实践
  • 开源:软件世界的革命者
  • Windows远程--如何使用IP访问服务器
  • 桌面开发 的设计模式(Design Patterns)基础知识
  • 【Java回顾】Day4 异常机制
  • Ruby 数据类型
  • Unity 从零开始的框架搭建1-3 关于命令模式的一些思考
  • 四、VSCODE 使用GIT插件