面向对象中的类和对象
1. 介绍
本文中,我们将讨论两个基本的面向对象编程概念之间的区别:对象和类。
2. 面向对象编程 OOP
面向对象编程(OOP)是一种关注“什么”而非“如何”的计算机编程模型。在它中,我们围绕数据来组织代码,而不是其他范式(例如函数式编程),在函数式编程中,我们的设计基于我们可以使用输入进行的操作。
基于 OOP 的设计的构建块是类、对象、属性和方法:
3. 类 vs. 对象
属性是对象数据的独立部分。方法是我们可以对对象进行的操作。但是,什么是类和对象,它们之间有什么区别?
3.1. 角色
类与对象的不同之处在于它在整体设计中的作用。
因此,类是一个模板,我们使用它来创建程序中所需的任意多个对象。它定义了对象的相关属性(属性)和行为(方法)。类的对象是指符合类指定并具有其定义的所有属性和方法的每个实体。
让我们来举个例子。
3.2. 示例
假设我们将一个人建模为一个类,我们将其命名为 Person
。我们可以在我们的应用中定义每个人将具有的以下四个属性:
- name
- age
- job_status
- gender
当然,我们可以添加其他属性,如姓氏、身高或体重。但是,关键是类应该只定义那些与我们的软件相关的属性。因此,如果我们编写的程序只需要了解每个人的上述四件事,那么我们应该只将它们定义为类的属性。
接下来,我们定义了两种方法来建模一个人可以利用这些属性做什么:
- GetNewJob()
- LeaveCurrentJob()
如果一个人得到了一份新工作,我们将调用 GetNewJob()
方法。它将把属性 job_status
从失业(unemployed )更改为已就业(employed)。类似地,为了将状态更改回失业,我们将调用 LeaveCurrentJob()
方法。
从示意图上看,这是我们的类:
然后,我们创建该类的两个对象:
正如我们所看到的,它们的属性在创建时具有特定的值。
总之,我们将类称为用户定义的类型,而我们可以将该类的对象视为该类型的变量。
3.3. 定义 vs. 实例化
我们可以说,类从来没有被创建过,只被定义过。这意味着类是真实世界实体的抽象模型,因此它只能有一个定义。它不可能存在于它的对象之间,只能描述它们。我们需要在编译/执行之前完全定义类。
相反,对象为真实世界的实体建模。因此,我们说它们可以被创建,这就是我们称之为实例化的过程。这种情况发生在运行时。
3.4. 属性
要创建一个对象,我们需要为其类指定的属性分配特定的值。
相反,要定义一个类,我们需要列出它的对象应该具有的所有属性和方法。对于每个属性,我们需要指定其名称和类型。在大多数编程语言中,我们还使用各种访问修饰符来限定每个属性,例如 Java 中的 private
或 public
。这些修饰符确定属性和方法是否在类及其对象外部可见。
3.5. 继承
类可以相互继承。子类包含其父类的定义。因此,父类的属性和方法也存在于子类上。这附带了一个条件,即父对象的属性和方法是可继承的。例如,Java 中的私有方法在子类中不可见。
而我们并不会说对象是继承于另一个对象。相反,对象的类型是它们所属的类。如果我们实例化一个对象 x 作为类 A 的实例,并让 B 是 A 的父对象,我们就说 x 是类型 A 和 B 的。由于 A 更具体,我们将 x 声明为类型 A 的变量,但也将其视为类型 B 的对象使用也不会有错。这就是多态。
3.6. 可变性
我们不能在定义类之后更改它。这就是 OOP 如何在大多数此类语言中的运作。
而我们可以在实例化后更改对象。这意味着我们可以改变它们的属性。的前提是他们类的定义允许我们这样做。
从这个角度来看,类是静态的,对象是动态的构造,因为前者不能但后者可以在代码执行过程中更改。
3.7. 内存
一旦我们创建了一个对象,操作系统就会为它分配内存。对象通常位于进程内存布局的堆部分。
类的定义也占用少量内存,但实际管理取决于编程语言。在 C++ 中,我们将类定义存储在过程代码部分。在 Java 中,类的处理方式与对象相同,因此它也存在于堆中。
4. 差异汇总
让我们快速总结一下类和对象之间的区别。下表罗列了两者之间的主要区别:
类 | 对象 |
抽象模型 | 具体的实体 |
类型 | 变量 |
模板(蓝图) | 模板的实例 |
不能修改 | 可以修改 |
定义属性类型 | 指定属性值 |
5. 结论
本文中,我们重新审视了面向对象编程及其两个基本结构:类和对象。
类是一组实体的形式化描述,这些实体属于一个公共定义,并具有公共属性和方法。它充当那些实体的编程模板,我们称之为对象。类定义对象是什么,它将具有什么属性,以及它的行为方式。因此,对象是类的实例,并且始终符合其类模型的模板。