- 帕斯卡教程
- 帕斯卡 - 主页
- 帕斯卡 - 概述
- Pascal - 环境设置
- 帕斯卡 - 程序结构
- Pascal - 基本语法
- Pascal - 数据类型
- Pascal - 变量类型
- 帕斯卡 - 常数
- 帕斯卡 - 运算符
- 帕斯卡 - 决策
- 帕斯卡 - 循环
- 帕斯卡 - 函数
- 帕斯卡 - 程序
- Pascal - 变量作用域
- 帕斯卡 - 弦乐
- 帕斯卡 - 布尔
- 帕斯卡 - 数组
- 帕斯卡 - 指针
- 帕斯卡 - 记录
- 帕斯卡 - 变体
- 帕斯卡 - 集合
- 帕斯卡 - 文件处理
- 帕斯卡 - 记忆
- 帕斯卡 - 单位
- 帕斯卡 - 日期和时间
- 帕斯卡 - 对象
- 帕斯卡 - 类
- 帕斯卡有用资源
- 帕斯卡 - 快速指南
- 帕斯卡 - 有用的资源
- 帕斯卡 - 讨论
Pascal - 面向对象
我们可以想象我们的宇宙是由不同的物体组成的,如太阳、地球、月亮等。同样,我们可以想象我们的汽车是由不同的物体组成的,如车轮、方向盘、齿轮等。同样,存在面向对象的编程概念,将一切视为对象并使用不同的对象来实现软件。在 Pascal 中,有两种结构数据类型用于实现现实世界的对象 -
- 对象类型
- 班级类型
面向对象的概念
在详细介绍之前,让我们定义与面向对象 Pascal 相关的重要 Pascal 术语。
对象- 对象是一种特殊的记录,包含像记录一样的字段;然而,与记录不同,对象包含过程和函数作为对象的一部分。这些过程和函数作为指向与对象类型关联的方法的指针。
类- 类的定义方式与对象几乎相同,但它们的创建方式有所不同。类分配在程序的堆上,而对象分配在堆栈上。它是指向对象的指针,而不是对象本身。
类的实例化- 实例化意味着创建该类类型的变量。由于类只是一个指针,因此当声明类类型的变量时,只会为该指针分配内存,而不是为整个对象分配内存。仅当使用其构造函数之一实例化该对象时,才会为该对象分配内存。类的实例也称为“对象”,但不要将它们与 Object Pascal 对象混淆。在本教程中,我们将为 Pascal 对象编写“Object”,为概念对象或类实例编写“object”。
成员变量- 这些是在类或对象内定义的变量。
成员函数- 这些是在类或对象内定义的函数或过程,用于访问对象数据。
成员的可见性- 对象或类的成员也称为字段。这些字段具有不同的可见性。可见性是指成员的可访问性,即可以访问这些成员的确切位置。对象具有三个可见性级别:公共、私有和受保护。类有五种可见性类型:公共、私有、严格私有、受保护和发布。我们将详细讨论可见性。
继承- 当一个类是通过继承父类的现有功能来定义时,则称它是继承的。这里子类将继承父类的全部或部分成员函数和变量。对象也可以被继承。
父类- 由另一个类继承的类。这也称为基类或超类。
子类- 从另一个类继承的类。这也称为子类或派生类。
多态性- 这是一个面向对象的概念,其中相同的函数可以用于不同的目的。例如,函数名称将保持不变,但可能采用不同数量的参数并且可以执行不同的任务。Pascal 类实现多态性。对象不实现多态性。
重载- 这是一种多态性,其中一些或所有运算符根据其参数的类型有不同的实现。类似地,函数也可以通过不同的实现来重载。Pascal 类实现重载,但对象没有。
数据抽象- 隐藏(抽象)实现细节的任何数据表示。
封装- 指的是我们将所有数据和成员函数封装在一起形成一个对象的概念。
构造函数- 指一种特殊类型的函数,每当类或对象形成对象时,都会自动调用该函数。
析构函数- 指一种特殊类型的函数,每当对象或类被删除或超出范围时,都会自动调用该函数。
定义 Pascal 对象
对象是使用类型声明来声明的。对象声明的一般形式如下 -
type object-identifier = object private field1 : field-type; field2 : field-type; ... public procedure proc1; function f1(): function-type; end; var objectvar : object-identifier;
让我们定义一个矩形对象,它有两个整数类型数据成员——长度和宽度,以及一些操作这些数据成员的成员函数和一个绘制矩形的过程。
type Rectangle = object private length, width: integer; public constructor init; destructor done; procedure setlength(l: inteter); function getlength(): integer; procedure setwidth(w: integer); function getwidth(): integer; procedure draw; end; var r1: Rectangle; pr1: ^Rectangle;
创建对象后,您将能够调用与该对象相关的成员函数。一个成员函数只能处理相关对象的成员变量。
下面的示例演示如何设置两个矩形对象的长度和宽度,并通过调用成员函数来绘制它们。
r1.setlength(3); r1.setwidth(7); writeln(' Draw a rectangle: ', r1.getlength(), ' by ' , r1.getwidth()); r1.draw; new(pr1); pr1^.setlength(5); pr1^.setwidth(4); writeln(' Draw a rectangle: ', pr1^.getlength(), ' by ' ,pr1^.getwidth()); pr1^.draw; dispose(pr1);
以下是一个完整的示例,展示如何在 Pascal 中使用对象 -
program exObjects; type Rectangle = object private length, width: integer; public procedure setlength(l: integer); function getlength(): integer; procedure setwidth(w: integer); function getwidth(): integer; procedure draw; end; var r1: Rectangle; pr1: ^Rectangle; procedure Rectangle.setlength(l: integer); begin length := l; end; procedure Rectangle.setwidth(w: integer); begin width :=w; end; function Rectangle.getlength(): integer; begin getlength := length; end; function Rectangle.getwidth(): integer; begin getwidth := width; end; procedure Rectangle.draw; var i, j: integer; begin for i:= 1 to length do begin for j:= 1 to width do write(' * '); writeln; end; end; begin r1.setlength(3); r1.setwidth(7); writeln('Draw a rectangle:', r1.getlength(), ' by ' , r1.getwidth()); r1.draw; new(pr1); pr1^.setlength(5); pr1^.setwidth(4); writeln('Draw a rectangle:', pr1^.getlength(), ' by ' ,pr1^.getwidth()); pr1^.draw; dispose(pr1); end.
当上面的代码被编译并执行时,它会产生以下结果 -
Draw a rectangle: 3 by 7 * * * * * * * * * * * * * * * * * * * * * Draw a rectangle: 5 by 4 * * * * * * * * * * * * * * * * * * * *
对象成员的可见性
可见性表示对象成员的可访问性。Pascal 对象成员具有三种类型的可见性 -
先生编号 | 可见性和可达性 |
---|---|
1 |
民众 会员可供本项目单位以外的其他单位使用 |
2 |
私人的 成员只能在当前单位访问。 |
3 | 受保护 这些成员仅可用于父对象的后代对象。 |
默认情况下,对象的字段和方法是公共的,并且导出到当前单元之外。
Pascal 对象的构造函数和析构函数 -
构造函数是特殊类型的方法,每当创建对象时都会自动调用它们。在 Pascal 中,只需使用关键字构造函数声明方法即可创建构造函数。通常,方法名称是 Init,但是,您可以提供自己的任何有效标识符。您可以将任意数量的参数传递到构造函数中。
析构函数是在对象销毁期间调用的方法。析构函数方法会销毁构造函数创建的任何内存分配。
下面的示例将为 Rectangle 类提供一个构造函数和一个析构函数,它将在创建对象时初始化矩形的长度和宽度,并在超出范围时销毁它。
program exObjects; type Rectangle = object private length, width: integer; public constructor init(l, w: integer); destructor done; procedure setlength(l: integer); function getlength(): integer; procedure setwidth(w: integer); function getwidth(): integer; procedure draw; end; var r1: Rectangle; pr1: ^Rectangle; constructor Rectangle.init(l, w: integer); begin length := l; width := w; end; destructor Rectangle.done; begin writeln(' Desctructor Called'); end; procedure Rectangle.setlength(l: integer); begin length := l; end; procedure Rectangle.setwidth(w: integer); begin width :=w; end; function Rectangle.getlength(): integer; begin getlength := length; end; function Rectangle.getwidth(): integer; begin getwidth := width; end; procedure Rectangle.draw; var i, j: integer; begin for i:= 1 to length do begin for j:= 1 to width do write(' * '); writeln; end; end; begin r1.init(3, 7); writeln('Draw a rectangle:', r1.getlength(), ' by ' , r1.getwidth()); r1.draw; new(pr1, init(5, 4)); writeln('Draw a rectangle:', pr1^.getlength(), ' by ',pr1^.getwidth()); pr1^.draw; pr1^.init(7, 9); writeln('Draw a rectangle:', pr1^.getlength(), ' by ' ,pr1^.getwidth()); pr1^.draw; dispose(pr1); r1.done; end.
当上面的代码被编译并执行时,它会产生以下结果 -
Draw a rectangle: 3 by 7 * * * * * * * * * * * * * * * * * * * * * Draw a rectangle: 5 by 4 * * * * * * * * * * * * * * * * * * * * Draw a rectangle: 7 by 9 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Destructor Called
Pascal 对象的继承
Pascal 对象可以选择从父对象继承。以下程序说明了 Pascal 对象中的继承。让我们创建另一个名为TableTop的对象,它继承自 Rectangle 对象。
program exObjects; type Rectangle = object private length, width: integer; public procedure setlength(l: integer); function getlength(): integer; procedure setwidth(w: integer); function getwidth(): integer; procedure draw; end; TableTop = object (Rectangle) private material: string; public function getmaterial(): string; procedure setmaterial( m: string); procedure displaydetails; procedure draw; end; var tt1: TableTop; procedure Rectangle.setlength(l: integer); begin length := l; end; procedure Rectangle.setwidth(w: integer); begin width :=w; end; function Rectangle.getlength(): integer; begin getlength := length; end; function Rectangle.getwidth():integer; begin getwidth := width; end; procedure Rectangle.draw; var i, j: integer; begin for i:= 1 to length do begin for j:= 1 to width do write(' * '); writeln; end; end; function TableTop.getmaterial(): string; begin getmaterial := material; end; procedure TableTop.setmaterial( m: string); begin material := m; end; procedure TableTop.displaydetails; begin writeln('Table Top: ', self.getlength(), ' by ' , self.getwidth()); writeln('Material: ', self.getmaterial()); end; procedure TableTop.draw(); var i, j: integer; begin for i:= 1 to length do begin for j:= 1 to width do write(' * '); writeln; end; writeln('Material: ', material); end; begin tt1.setlength(3); tt1.setwidth(7); tt1.setmaterial('Wood'); tt1.displaydetails(); writeln; writeln('Calling the Draw method'); tt1.draw(); end.
以下是应注意的要点 -
Tabletop对象继承了 Rectangle 对象的所有成员。
TableTop中也有一个绘制方法。当使用TableTop对象调用draw方法时,TableTop 的draw 被调用。
有一个名为self的隐式实例,它引用该对象的当前实例。
当上面的代码被编译并执行时,它会产生以下结果 -
Table Top: 3 by 7 Material: Wood Calling the Draw Method * * * * * * * * * * * * * * * * * * * * * Material: Wood