程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 第十九章-Delphi自定義部件開發(一)(3)

第十九章-Delphi自定義部件開發(一)(3)

編輯:Delphi

19.2.1.5 編寫部件的面向對象技術

部件使用者在Delphi環境中開發,將遇到在包含數據和方法的對象。他們將在設計階段和運行階段操作對象,而編寫部件將比他們需要更多的關於對象的知識,因此,你應當熟悉Delphi的面向對象的程序設計。

1. 建立部件

部件用戶和部件編寫者最基本的區別是用戶處理對象的實例,而編寫者創建新的對象類型。這個概念是面向對象程序設計的基礎。例如,用戶創建了一個包含兩個按鈕的窗體,一個標為OK,另一個標為Cancel,每個都是TButton的實例,通過給Text、default和Cancel等屬性賦不同的值,給OnClick事件賦予不同的處理過程,用戶產生了兩個不同的實例。

建立新部件一般有兩個理由

● 改變類型的缺省情況,避免反復

● 為部件增加新的功能

目的都是為了建立可重用對象。如果從將來重用的角度預先計劃和設計,能節省一大堆將來的工作。

在程序設計中,避免不必要的重復是很重要的。如果發現在代碼中一遍又一遍重寫相同的行,就應當考慮將代碼放在子過程或函數中,或干脆建立一個函數庫。

設計部件也是這個道理,如果總是改變相同的屬性或相同的方法調用,那應創建新部件。

創建新部件的另一個原因是想給已有的部件增加新的功能。你可以從已有部件直接繼承(如ListBox)或從抽象對象類型繼承(如TComponent,TControl)。你雖然能為部件增加新功能,但不能將原有部件的屬性移走,如果要這樣做的話,就從該父對象的祖先對象繼承。

2. 控制部件的訪向

Object Pascal語言為對象的各部分提供了四個級別的訪問控制。訪問控制讓你定義什麼代碼能訪問對象的哪一部分。通過描述訪問級別,定義了部件的接口。如果合理安排接口,將提高部件的可用性和重用性。

除非特地描述,否則加在對象裡的域、方法和屬性的控制級別是published,這意味著任何代碼可以訪問整個對象。

下表列出各保護級別:

表19.2 對象定義中的保護級別

━━━━━━━━━━━━━━━━━━━

保護級 用處

───────────────────

private 隱藏實現細節

protected 定義開發者接口

public 定義運行時接口

published 定義設計時接口

━━━━━━━━━━━━━━━━━━━

所有的保護級都在單元級起作用。如果對象的某一部分在庫單元中的一處可訪向,則在該庫單元任意處都可訪向。

⑴ 隱藏實現細節

如果對象的某部分被聲明為private,將使其它庫單元的代碼無法訪問該部分,但包含聲明的庫單元中的代碼可以訪問,就好象訪問public一樣,這是和C++不同的。

對象類型的private部分對於隱藏詳細實現是很重要的。既然對象的用戶不能訪問,private部分,你就能改變對象的實現而不影響用戶代碼。

下面是一個演示防止用戶訪問private域的例子:

unit HideInfo;

interface

uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms,

Dialogs;

type

TSecretForm = class(TForm) { 聲明新的窗體窗口 }

procedure FormCreate(Sender: TObject);

private { declare private part }

FSecretCode: Integer; { 聲明private域 }

end;

var

SecretForm: TSecretForm;

implementation

procedure TSecretForm.FormCreate(Sender: TObject);

begin

FSecretCode := 42;

end;

end.

unit TestHide; { 這是主窗體庫單元 }

interface

uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms,

Dialogs, HideInfo; { 使用帶TSecretForm聲明的庫單元 }

type

TTestForm = class(TForm)

procedure FormCreate(Sender: TObject);

end;

var

TestForm: TTestForm;

implementation

procedure TTestForm.FormCreate(Sender: TObject);

begin

SecretForm.FSecretCode := 13; {編譯過程將以"Field identifier expected"錯誤停止}

end;

end.

⑵ 定義開發者接口

將對象某部分聲明為protected,可使在包含該部件聲明的庫單元之外的代碼無法訪問,就象private部分。protected部分的不同之處是,某對象繼承該對象,則包含新對象的庫單元可以訪問protected部分,你能使用protected聲明定義開發者的接口。也就是說。對象的用戶不能訪向protected部分,但開發者通過繼承就可能做到,這意味著你能通過protected部分的可訪問性使部件編寫者改變對象工作方式,而又不使用戶見到這些細節。

⑶ 定義運行時接口

將對象的某一部分定義為public可使任何代碼訪問該部分。如果你沒有對域方法或屬性加以private、protected、public的訪問控制描述。那麼該部分就是published。

因為對象的public部分可在運行時為任何代碼訪問,因此對象的public部分被稱為運行接口。運行時接口對那些在設計時沒有意義的項目,如依靠運行時信息的和只讀的屬性,是很有用的。那些設計用來供用戶調用的方法也應放在運行時接口中。

下例是一個顯示兩個定義在運行時接口的只讀屬性的例子:

type

TSampleComponent = class(TComponent)

private

FTempCelsius: Integer; { 具體實現是private }

function GetTempFahrenheit: Integer;

public

property TempCelsius: Integer read FTempCelsius; { 屬性是public }

property TempFahrenheit: Integer read GetTempFahrenheit;

end;

function GetTempFahrenheit: Integer;

begin

Result := FTempCelsius * 9 div 5 + 32;

end;

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved