
- Pascal 教程
- Pascal - 首頁
- Pascal - 概述
- Pascal - 環境設定
- Pascal - 程式結構
- Pascal - 基本語法
- Pascal - 資料型別
- Pascal - 變數型別
- Pascal - 常量
- Pascal - 運算子
- Pascal - 決策
- Pascal - 迴圈
- Pascal - 函式
- Pascal - 過程
- Pascal - 變數作用域
- Pascal - 字串
- Pascal - 布林值
- Pascal - 陣列
- Pascal - 指標
- Pascal - 記錄
- Pascal - 變體
- Pascal - 集合
- Pascal - 檔案處理
- Pascal - 記憶體
- Pascal - 單元
- Pascal - 日期和時間
- Pascal - 物件
- Pascal - 類
- Pascal 有用資源
- Pascal - 快速指南
- Pascal - 有用資源
- Pascal - 討論
Pascal - 面向物件
我們可以想象我們的宇宙是由不同的物體組成的,例如太陽、地球、月球等。類似地,我們可以想象我們的汽車是由不同的物體組成的,例如車輪、方向盤、齒輪等。同樣,存在面向物件的程式設計概念,它假設一切都是物件,並使用不同的物件來實現軟體。在 Pascal 中,有兩種結構化資料型別用於實現現實世界中的物件:
- 物件型別
- 類型別
面向物件的概念
在深入瞭解之前,讓我們定義與面向物件 Pascal 相關的重要的 Pascal 術語。
物件 - 物件是一種特殊的記錄,它包含類似於記錄的欄位;但是,與記錄不同,物件包含過程和函式作為物件的一部分。這些過程和函式作為指向與物件型別關聯的方法的指標儲存。
類 - 類的定義方式幾乎與物件相同,但建立方式有所不同。類分配在程式的堆上,而物件分配在棧上。它是指向物件的指標,而不是物件本身。
類的例項化 - 例項化意味著建立該類型別的變數。由於類只是一個指標,因此當宣告類型別的變數時,僅為指標分配記憶體,而不是為整個物件分配記憶體。只有當它使用其建構函式之一進行例項化時,才會為物件分配記憶體。類的例項也稱為“物件”,但不要將其與 Object Pascal 物件混淆。在本教程中,我們將使用“Object”表示 Pascal 物件,使用“object”表示概念物件或類例項。
成員變數 - 這些是在類或物件內部定義的變數。
成員函式 - 這些是在類或物件內部定義的函式或過程,用於訪問物件資料。
成員的可見性 - 物件或類的成員也稱為欄位。這些欄位具有不同的可見性。可見性指的是成員的可訪問性,即這些成員在何處可訪問。物件具有三個可見性級別:public、private 和 protected。類有五種可見性型別:public、private、strictly private、protected 和 published。我們將詳細討論可見性。
繼承 - 當透過繼承父類的現有功能來定義類時,則稱其為繼承。此處子類將繼承父類所有或部分成員函式和變數。物件也可以被繼承。
父類 - 被另一個類繼承的類。這也被稱為基類或超類。
子類 - 從另一個類繼承的類。這也被稱為子類或派生類。
多型性 - 這是面向物件的概念,其中同一個函式可以用於不同的目的。例如,函式名稱將保持不變,但它可以接受不同數量的引數,並且可以執行不同的任務。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;
讓我們定義一個矩形物件,它有兩個整數型別的資料成員 - 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 物件成員具有三種類型的可見性:
序號 | 可見性和可訪問性 |
---|---|
1 |
Public 成員可被程式單元之外的其他單元使用 |
2 |
Private 成員僅在當前單元中可訪問。 |
3 | Protected 成員僅對從父物件派生的物件可用。 |
預設情況下,物件的欄位和方法是 public 的,並且匯出到當前單元之外。
Pascal 物件的建構函式和解構函式:
建構函式是一種特殊的型別的方法,每當建立物件時都會自動呼叫它。您只需使用關鍵字 constructor 宣告方法即可在 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 中也存在一個 draw 方法。當使用 TableTop 物件呼叫 draw 方法時,將呼叫 TableTop 的 draw。
有一個名為self的隱式例項,它引用物件的當前例項。
當以上程式碼編譯並執行時,會產生以下結果:
Table Top: 3 by 7 Material: Wood Calling the Draw Method * * * * * * * * * * * * * * * * * * * * * Material: Wood