对象(Objects)
我们可以想象我们的宇宙由不同的物体组成,如太阳,地球,月亮等。同样,我们可以想象我们的汽车由不同的物体组成,如车轮,转向,齿轮等。同样,有面向对象的编程概念,假设所有内容都是对象,并使用不同的对象实现软件。 在Pascal中,有两种用于实现现实世界对象的结构数据类型 -
- Object types
- Class types
Object-Oriented Concepts
在我们详细介绍之前,让我们定义与面向对象Pascal相关的重要Pascal术语。
Object - 对象是一种特殊的记录,包含记录等字段; 但是,与记录不同,对象包含过程和函数作为对象的一部分。 这些过程和函数作为指向与对象类型相关的方法的指针。
Class - 类的定义方式与对象几乎相同,但它们的创建方式有所不同。 Class在程序的Heap上分配,而Object在Stack上分配。 它是指向对象的指针,而不是对象本身。
Instantiation of a class - 实例化意味着创建该类类型的变量。 由于类只是一个指针,当声明类类型的变量时,只为指针分配内存,而不是为整个对象分配内存。 只有在使用其构造函数对其进行实例化时,才会为该对象分配内存。 类的实例也称为“对象”,但不要将它们与Object Pascal对象混淆。 在本教程中,我们将为Pascal对象编写'Object',为概念对象或类实例编写'object'。
Member Variables - 这些是在类或对象中定义的变量。
Member Functions - 这些是在类或对象中定义的函数或过程,用于访问对象数据。
Visibility of Members - 对象或类的成员也称为字段。 这些领域具有不同的可见性。 可见性是指成员的可访问性,即这些成员可以访问的确切位置。 对象有三个可见性级别:public,private和protected。 类具有五种可见性类型:公共,私有,严格私有,受保护和已发布。 我们将详细讨论可见性。
Inheritance - 当通过继承父类的现有功能来定义类时,则认为它是继承的。 这里子类将继承父类的所有或几个成员函数和变量。 对象也可以继承。
Parent Class - 由另一个类继承的类。 这也称为基类或超类。
Child Class - 从另一个类继承的类。 这也称为子类或派生类。
Polymorphism - 这是一个面向对象的概念,其中相同的功能可用于不同的目的。 例如,函数名称将保持不变,但它可能需要不同数量的参数,并且可以执行不同的任务。 Pascal类实现多态。 对象不实现多态。
Overloading - 它是一种多态,其中一些或所有运算符具有不同的实现,具体取决于它们的参数类型。 类似地,函数也可以通过不同的实现来重载。 Pascal类实现重载,但Objects不实现。
Data Abstraction - 隐藏实现细节(抽象)的任何数据表示。
Encapsulation - 指我们将所有数据和成员函数封装在一起以形成对象的概念。
Constructor - 指特殊类型的函数,只要从类或对象形成对象,就会自动调用该函数。
Destructor函数 - 指一种特殊类型的函数,只要删除对象或类或超出范围,就会自动调用该函数。
定义Pascal对象
使用类型声明声明对象。 对象声明的一般形式如下 -
type object-identifier = object
private
field1 : field-type;
field2 : field-type;
...
public
procedure proc1;
function f1(): function-type;
end;
var objectvar : object-identifier;
让我们定义一个Rectangle Object,它有两个整数类型的数据成员 - length和width以及一些用于操作这些数据成员的成员函数和一个绘制矩形的过程。
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对象成员有三种类型的可见性 -
Sr.No | 可见性和可访问性 |
---|---|
1 | Public 成员可以由程序单元外的其他单元使用 |
2 | Private 成员只能在当前单位中访问。 |
3 | Protected 成员仅可用于父对象的后续对象。 |
默认情况下,对象的字段和方法是公共的,并导出到当前单位之外。
Pascal对象的构造函数和析构函数 -
Constructors是特殊类型的方法,只要创建对象,就会自动调用这些方法。 只需通过声明一个带有关键字构造函数的方法,就可以在Pascal中创建一个构造函数。 通常,方法名称为Init,但是,您可以提供自己的任何有效标识符。 您可以将任意数量的参数传递给构造函数。
Destructors构函数是在销毁对象期间调用的方法。 析构函数方法会破坏构造函数创建的任何内存分配。
下面的示例将为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也有一个draw方法。 使用TableTop对象调用draw方法时,将调用TableTop的绘制。
有一个名为self的隐式实例,它引用了对象的当前实例。
编译并执行上述代码时,会产生以下结果 -
Table Top: 3 by 7
Material: Wood
Calling the Draw Method
* * * * * * *
* * * * * * *
* * * * * * *
Material: Wood