我们可以想像我们的宇宙不同的物体,如太阳,地球,月亮等,同样,我们可以想像我们的车是面向对象编程的概念,认为一切作为对象,不同的对象,如车轮,转向系统,齿轮等同样的方式作出实现软件使用不同的对象。 Pascal中有两种结构使用的数据类型,以实现一个真实的世界中的对象:
-
对象类型
-
类类型
面向对象概念:
在我们继续之前,让我们来定义相关的面向对象Pascal重要的详细条款。
-
对象:一个对象是一个特殊的记录,其中包含等领域的纪录,但不同的记录对象包含存储过程和函数对象的一部分。这些过程和函数指针的方法与对象的类型。
-
类:一类中定义的几乎相同的方式作为一个对象,但方式创建它们是有区别的。类是分配在堆上的程序,而对象是分配在栈上。它是一个指针的对象,而不是对象本身。
-
类实例:实例化意味着创建该类类型的变量。一类是只是一个指针,类类型的变量被声明时,分配的内存的指针,而不是整个对象。只有当它是使用它的构造函数的一个实例,内存被分配的对象。一个类的实例也被称为“对象”,但不要混淆他们与对象Pascal对象。在本教程中,我们将编写为Pascal对象“对象”的概念对象或类的实例。
-
成员变量:这些都是在一个类中定义的变量或对象。
-
成员函数:这些内部定义一个类或对象,用于访问对象数据的函数或程序。
-
访问成员:一个对象或类的成员,也被称为字段。这些字段有不同的可见性。能见度是指可访问的成员,即,正是这些成员可以访问。对象有三种可见性级别:公共,私有和保护。类有五个可见性类型:公共,私人,严格保密,保护和公开。我们将讨论在细节的可见性。
-
继承:当定义一个类继承父类的现有功能,那么它被认为是继承。这里的子类会继承父类的所有或几个成员函数和变量。对象也可以被继承。
-
父类:一类是继承另一个类。这也被称为基类或超类。
-
子类:一个类从另一个类继承。这也被称为一个子类或派生类。
-
多态性:这是一种面向对象的概念相同的功能,可用于不同的目的。例如,函数名相同,但它可能需要不同数量的参数,可以做不同的任务。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对象的成员有三种类型的可见性:
Visibility | Accessibility |
---|---|
Public | The members can be used by other units outside the program unit |
Private | The members are only accessible in the current unit. |
Protected | The members are available only to objects descended from the parent object. |
默认情况下,公共领域和对象的方法是,在现行的单元并导出。
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对象的继承。让我们创建另一个对象命名为桌面,这是继承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.
以下是重要的点,应记下:
-
对象桌面继承Rectangle对象的所有成员。
-
在TableTop 有一个draw方法。当抽奖方法被调用时使用的TableTop 对象,TableTop 型draw方法被调用。
-
有一个隐含的实例命名为self,指的是对象的当前实例
上面的代码编译和执行时,它会产生以下结果:
Table Top: 3 by 7 Material: Wood Calling the Draw Method * * * * * * * * * * * * * * * * * * * * * Material: Wood
Pascal类
Pascal的的对象表现出一定的特点,面向对象南规范。它们实现了封装,数据隐藏和继承,但他们也有局限性。例如,Pascal对象不参加的多态性。因此类被广泛用于实施适当的面向对象的程序中的行为,特别是基于GUI的软件。
我们已经看到了Pascal的的对象表现出一定的特点,面向对象南规范。它们实现了封装,数据隐藏和继承,但他们也有局限性。例如,Pascal对象不参加的多态性。因此类被广泛用于实施适当的面向对象的程序中的行为,特别是基于GUI的软件。
一个类被定义为对象,在几乎相同的方式,不过是一个指针,指向一个对象,而不是对象本身。从技术上讲,这意味着类被分配在堆上的程序,而对象是在堆栈上分配。换句话说,当你声明一个变量的对象类型,它会占用尽可能多的空间在堆栈中的对象的大小,但是当你声明一个类类型的变量,它会始终以指针的大小。在堆栈中。实际的类数据是在堆上。
定义Pascal类:
作为一个对象以相同的方式,使用的类型声明一个类被声明。类的声明的一般形式如下:
type class-identifier = class
private
field1 : field-type;
field2 : field-type;
...
public
constructor create();
procedure proc1;
function f1(): function-type;
end;
var classvar : class-identifier;
值得要注意以下要点:
-
类的定义应该根据类型声明的程序的一部分
-
使用class关键字定义一个类
-
字段是存在于每一个类的实例的数据项
-
在定义一个类中声明的方法
-
有一个预定义的构造函数称为根类创建。每一个抽象类,每一个具体类是根的子孙,因此所有的类至少有一个构造函数。
-
有一个预定义的析构函数被称为根类中的销毁。每一个抽象类,每一个具体类是根的后代,所以,所有的类都至少有一个析构函数。
让我们定义一个Rectangle类,它有两个整数类型的数据成员 - 长度和宽度,一些成员函数来处理这些数据成员和一个程序来绘制矩形。
type
Rectangle = class
private
length, width: integer;
public
constructor create(l, w: integer);
procedure setlength(l: integer);
function getlength(): integer;
procedure setwidth(w: integer);
function getwidth(): integer;
procedure draw;
end;
让我们写一个完整的程序,将创建一个矩形类的一个实例并绘制矩形。这是相同的例子中我们讨论Pascal对象使用。你会发现这两个程序几乎相同,但下列情况除外:
-
您将需要包括{$mode objfpc}指令,使用类
-
您将需要包括使用构造函数的指令{$M+}
-
对象实例化类的实例是不同的。只有声明的变量没有创建空间的情况下使用构造函数创建分配内存。
下面是完整的示例:
{$mode objfpc}
{$m+}
program exClass;
type
Rectangle = class
private
length, width: integer;
public
constructor create(l, w: integer);
procedure setlength(l: integer);
function getlength(): integer;
procedure setwidth(w: integer);
function getwidth(): integer;
procedure draw;
end;
var
r1: Rectangle;
constructor Rectangle.create(l, w: integer);
begin
length := l;
width := w;
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:= Rectangle.create(3, 7);
writeln(' Darw Rectangle: ', r1.getlength(), ' by ' , r1.getwidth());
r1.draw;
r1.setlength(4);
r1.setwidth(6);
writeln(' Darw Rectangle: ', r1.getlength(), ' by ' , r1.getwidth());
r1.draw;
end.
When the above code is compiled and executed, it produces following result:
$ ./exClass
Darw Rectangle: 3 by 7
* * * * * * *
* * * * * * *
* * * * * * *
Darw Rectangle: 4 by 6
* * * * * *
* * * * * *
* * * * * *
* * * * * *