咱們能夠想像咱們的宇宙不一樣的物體,如太陽,地球,月亮等,一樣,咱們能夠想像咱們的車是面向對象編程的概念,認爲一切做爲對象,不一樣的對象,如車輪,轉向系統,齒輪等一樣的方式做出實現軟件使用不一樣的對象。 Pascal中有兩種結構使用的數據類型,以實現一個真實的世界中的對象:編程
對象類型yii
類類型ide
在咱們繼續以前,讓咱們來定義相關的面向對象Pascal重要的詳細條款。函數
對象:一個對象是一個特殊的記錄,其中包含等領域的紀錄,但不一樣的記錄對象包含存儲過程和函數對象的一部分。這些過程和函數指針的方法與對象的類型。spa
類:一類中定義的幾乎相同的方式做爲一個對象,但方式建立它們是有區別的。類是分配在堆上的程序,而對象是分配在棧上。它是一個指針的對象,而不是對象自己。指針
類實例:實例化意味着建立該類類型的變量。一類是隻是一個指針,類類型的變量被聲明時,分配的內存的指針,而不是整個對象。只有當它是使用它的構造函數的一個實例,內存被分配的對象。一個類的實例也被稱爲「對象」,但不要混淆他們與對象Pascal對象。在本教程中,咱們將編寫爲Pascal對象「對象」的概念對象或類的實例。code
成員變量:這些都是在一個類中定義的變量或對象。對象
成員函數:這些內部定義一個類或對象,用於訪問對象數據的函數或程序。繼承
訪問成員:一個對象或類的成員,也被稱爲字段。這些字段有不一樣的可見性。能見度是指可訪問的成員,即,正是這些成員能夠訪問。對象有三種可見性級別:公共,私有和保護。類有五個可見性類型:公共,私人,嚴格保密,保護和公開。咱們將討論在細節的可見性。教程
繼承:當定義一個類繼承父類的現有功能,那麼它被認爲是繼承。這裏的子類會繼承父類的全部或幾個成員函數和變量。對象也能夠被繼承。
父類:一類是繼承另外一個類。這也被稱爲基類或超類。
子類:一個類從另外一個類繼承。這也被稱爲一個子類或派生類。
多態性:這是一種面向對象的概念相同的功能,可用於不一樣的目的。例如,函數名相同,但它可能須要不一樣數量的參數,能夠作不一樣的任務。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聲明方法與關鍵字的構造函數。可是傳統的方法的名稱是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對象的繼承。讓咱們建立另外一個對象命名爲桌面,這是繼承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對象不參加的多態性。所以類被普遍用於實施適當的面向對象的程序中的行爲,特別是基於GUI的軟件。
咱們已經看到了Pascal的的對象表現出必定的特色,面向對象南規範。它們實現了封裝,數據隱藏和繼承,但他們也有侷限性。例如,Pascal對象不參加的多態性。所以類被普遍用於實施適當的面向對象的程序中的行爲,特別是基於GUI的軟件。
一個類被定義爲對象,在幾乎相同的方式,不過是一個指針,指向一個對象,而不是對象自己。從技術上講,這意味着類被分配在堆上的程序,而對象是在堆棧上分配。換句話說,當你聲明一個變量的對象類型,它會佔用盡量多的空間在堆棧中的對象的大小,可是當你聲明一個類類型的變量,它會始終以指針的大小。在堆棧中。實際的類數據是在堆上。
做爲一個對象以相同的方式,使用的類型聲明一個類被聲明。類的聲明的通常形式以下:
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 * * * * * * * * * * * * * * * * * * * * * * * *