日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

▼▲Delphi面向对象编程的20条规则

發(fā)布時(shí)間:2025/3/15 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ▼▲Delphi面向对象编程的20条规则 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

▼▲Delphi面向?qū)ο缶幊痰?0條規(guī)則(轉(zhuǎn)載)

樓主ZyxIp(絕望中...)2003-09-02 14:28:07 在 Delphi / VCL組件開發(fā)及應(yīng)用 提問

作者簡(jiǎn)介 ? ?
? Marco ? Cantu是一個(gè)知名的Delphi專家,他曾出版過《精通Delphi》系列叢書,《Delphi開發(fā)手冊(cè)》以及電子書《精通Pascal》(該電子書可在網(wǎng)上免費(fèi)獲得)。他講授的課題是Delphi基礎(chǔ)和高級(jí)開發(fā)技巧。你可以通過他的網(wǎng)站(www.marcocantu.com)獲得更多關(guān)于他的信息,你也可以他的公共新聞組和他聯(lián)系,詳情請(qǐng)參見他的網(wǎng)站。 ? ?
? ?
? 前言 ? ?
? 大多數(shù)Delphi程序員都像使用Visual ? Basic ? 那樣使用他們手頭上開發(fā)工具,而絲毫沒有意識(shí)到Delphi的強(qiáng)大功能,更談不上使用這些功能了。(寫到這里,編輯惶恐的舉起了手,怎么可能呢?)Delphi和Visual ? Basic不同,Delphi完全建立在面向?qū)ο蠼Y(jié)構(gòu)上,這不僅影響到VCL的結(jié)構(gòu),而且影響到使用Delphi開發(fā)的每一個(gè)程序。 ? ?
? 在本文中,我不想涉及到面向?qū)ο缶幊?#xff08;OOP)的所有理論,只是提出一些簡(jiǎn)單的經(jīng)驗(yàn)規(guī)則。希望這些規(guī)則能夠幫助改善你的程序結(jié)構(gòu)。無論你開發(fā)的是何種類型的程序,這些經(jīng)驗(yàn)規(guī)則都是適用的。你應(yīng)當(dāng)把他們當(dāng)作一些建議,記住他們并把他們應(yīng)用到你開發(fā)的程序中去。 ? ?
? 關(guān)于面向?qū)ο缶幊?#xff0c;我想強(qiáng)調(diào)的一個(gè)關(guān)鍵原理是封裝。我們都希望創(chuàng)建一些靈活而且強(qiáng)健的類,因?yàn)檫@樣的類允許我們以后修改他們的實(shí)現(xiàn)方法而不影響到程序中的其他部分,這正是封裝給我們帶來的好處。雖然封裝不是創(chuàng)建一個(gè)好的面向?qū)ο蟪绦虻奈ㄒ粯?biāo)準(zhǔn),但是它構(gòu)成了面相對(duì)象編程的基礎(chǔ),所以在本文中我也許會(huì)過多的強(qiáng)調(diào)封裝性,請(qǐng)不要感到奇怪,我有足夠充分的理由這么做。 ? ?
? 最后,我想說明這樣一個(gè)事實(shí):本文將主要集中說明窗體(Forms)的開發(fā)(雖然其中的一些規(guī)則對(duì)于組件的開發(fā)同樣適用),因此這些規(guī)則對(duì)于所有的Delphi程序員都是適用的。那些編寫組件的程序員必須把面相對(duì)象編程和類(Class)作為核心的元素,但是對(duì)于那些使用組件編程的程序員,他們時(shí)常會(huì)忘記面向?qū)ο蟆?duì)于他們,本文可以當(dāng)作一個(gè)提示,提醒他們始終記住面向?qū)ο缶幊?? ?
? ?
? 第一部分:窗體是類(A ? Form ? is ? A ? Class)(rule ? 1-rule ? 15) ? ?
? 程序員常常將窗體看作是對(duì)象,而事實(shí)上窗體是類。兩者的差別在于你創(chuàng)建基于相同的窗體類的多個(gè)窗體對(duì)象。令人感到疑惑的是Delphi為你定義的每一個(gè)窗體類創(chuàng)建了一個(gè)默認(rèn)的全局對(duì)象。這對(duì)于新手來說是相當(dāng)方便的,但是這同樣會(huì)使他們形成壞習(xí)慣。 ? ?
? ?
? 第二部分:繼承(Inheritance)(rule ? 15-rule ? 20) ? ?
? 在講述了一系列關(guān)于類特別是關(guān)于窗體類的規(guī)則后,第二部分將是一些關(guān)于類的繼承性以及可視化窗體繼承的建議和技巧。 ? ?
? ?
? 關(guān)于代碼 ? ?
? 本文中所有的代碼段都可以在本期雜志(《The ? Delphi ? Magazine》 ? Issue ? 47)附帶的磁盤中的OopDemo工程中找到。你特別應(yīng)該查看例程中的frm2 ? 單元(unit)和inher單元。如果你想使用這些代碼,請(qǐng)注意構(gòu)造器必要的初始化設(shè)置以及私有組件參照,同時(shí)有必要設(shè)置好窗體的OldCreateOrder屬性。否則,帶有組件的窗體構(gòu)造器的初始化代碼將在窗體的OnCreate事件之前得到執(zhí)行。 ? ?
? 在這張磁盤上你還可以找到OOP ? 窗體向?qū)У牡谝话娴木幾g包,不過我更希望你訪問我的網(wǎng)站獲得該程序的更完整的版本。 ? ?
? 規(guī)則一:為每一個(gè)類創(chuàng)建一個(gè)單元(One ? Class,One ? Unit) ? ?
? 請(qǐng)始終牢記這一點(diǎn):類的私有(private)和保護(hù)(protected)的部分只對(duì)于其他單元中的類和過程(procedure)才是隱藏的.因此,如果你想得到有效的封裝性,你應(yīng)該為每一個(gè)類使用一個(gè)不同的單元。對(duì)于一些簡(jiǎn)單的類,比如那些繼承其他類的類,你可以使用一個(gè)共享的單元。不過共享同一個(gè)單元的類的數(shù)目是受到限制的:不要在一個(gè)簡(jiǎn)單的單元里放置超過20個(gè)復(fù)雜的類,雖然Borland公司的VCL代碼曾經(jīng)這樣做過。 ? ?
? 如果你使用窗體的時(shí)候,Delphi會(huì)默認(rèn)的遵循“一個(gè)類使用一個(gè)單元”的規(guī)則,這對(duì)于程序員來說也是十分方便的。當(dāng)你向你的項(xiàng)目中添加一個(gè)沒有窗體的類時(shí),Delphi也會(huì)創(chuàng)建一個(gè)新的獨(dú)立的單元。 ? ?
? ?
? 規(guī)則二:為組件命名(Name ? Components) ? ?
? 為每一個(gè)窗體和單元給出一個(gè)有意義的名字是十分重要的。窗體和單元的名字必須是不同的,不過我趨向于為他們兩者使用相似的名字,如對(duì)于關(guān)于窗體和單元可以為他們使用AboutForm ? 和About.pas. ? ?
? 為組件使用帶有描述性的名字同樣十分重要。最常見的命名方式是使用類的小寫字母開頭,再加上組件的功能,如BtnAdd ? 或者editName。采用這樣的命名方式為組件命名可能會(huì)有很多相似的名字,而且也沒有一個(gè)最好的名字,到底應(yīng)該選擇那一個(gè)應(yīng)該依據(jù)你的個(gè)人愛好而定。 ? ?
? ?
? 規(guī)則三:為事件命名(Name ? Events) ? ?
? 對(duì)于事件處理方法給出合適的名字更加重要。如果你對(duì)于組件給出了一個(gè)合適的名字,那么系統(tǒng)默認(rèn)的名字ButtonClick將變成BtnAddClick。雖然從這個(gè)名字中我們可以猜到這個(gè)事件處理程序的功能,但是我認(rèn)為使用一個(gè)能夠描述該方法的作用的名字,而不是采用Delphi附加的名字是一種更好的方式。例如,BtnAdd按鈕的OnClick事件可以命名成AddToList。這會(huì)使得你的程序可讀性更強(qiáng),特別是當(dāng)你在這個(gè)類的其他方法中調(diào)用這個(gè)事件處理程序時(shí),而且這會(huì)幫助程序員為類似的事件或是不同的組件選用相同的方法。不過我必須聲明,使用動(dòng)作(Actions)是目前開發(fā)重要的程序時(shí)我最喜歡的方法。 ? ?
? ?
? 規(guī)則四:使用窗體方法(Use ? Form ? Methods) ? ?
? 窗體都是一些類,因此窗體的代碼是以方法組織的。你可以向窗體中添加事件處理程序,這些處理程序完成一些特別的功能,而且他們能被其他方法調(diào)用。除了事件處理方法外,你還可以向窗體添加完成動(dòng)作的特別定義的方法以及訪問窗體狀態(tài)的方法。在窗體中添加一些公共的(Public)方法供其他窗體調(diào)用要比其他窗體直接操作他的組件要好。 ? ?
? ?
? 規(guī)則5:添加窗體構(gòu)造器(Add ? Form ? Constructors) ? ?
? 在運(yùn)行時(shí)創(chuàng)建的第二個(gè)窗體除了一個(gè)默認(rèn)的構(gòu)造器(從Tcomponent ? 類繼承而來)外還會(huì)提供其他特殊的構(gòu)造器。如果你不需要考慮和Delphi4以前的版本的兼容性問題,我建議你重載(Overload)Create方法,添加必要的初始化參數(shù)。具體代碼可參見下面的代碼: ? ?
? Public ? ?
? Constructor ? Create(Text:string): ? reintroduce ? ; ? overload; ? ?
? Constructor ? TformDialog.Create(Text:string); ? ?
? Begin ? ?
? Inherited ? Create(Application); ? ?
? Edit1.Text:=Text; ? ?
? End; ? ?
? 規(guī)則6:避免全局變量(Avoid ? Global ? Variables) ? ?
? 應(yīng)該避免使用全局變量(就是那些在單元的interface ? 部分定義的變量)。下面將會(huì)有一些建議幫助你如何去做。 ? ?
? 如果你需要為窗體存儲(chǔ)額外的數(shù)據(jù),你可以向窗體類中添加一些私有數(shù)據(jù)。這種情況下,每一個(gè)窗體實(shí)例都會(huì)有自己的數(shù)據(jù)副本。你可以使用單元變量(在單元的implementation部分定義的變量)聲明那些供窗體類的多個(gè)實(shí)例共享的數(shù)據(jù)。 ? ?
? 如果你需要在不同類型的窗體之間共享數(shù)據(jù),你可以把他們定義在主窗體里來實(shí)現(xiàn)共享,或者使用一個(gè)全局變量,使用方法或者是屬性來獲得數(shù)據(jù)。 ? ?
? ?
? 規(guī)則7:永遠(yuǎn)不要在Tform1類中使用Form1(Never ? Use ? Form1 ? in ? Tform1) ? ?
? 你應(yīng)該避免在類的方法中使用一個(gè)特定的對(duì)象名稱,換句話說,你不應(yīng)該在TForm1類的方法中直接使用Form1.如果你確實(shí)需要使用當(dāng)前的對(duì)象,你可以使用Self關(guān)鍵字。請(qǐng)牢記:大多數(shù)時(shí)候你都沒有必要直接使用當(dāng)前對(duì)象的方法和數(shù)據(jù)。 ? ?
? 如果你不遵循這條規(guī)則,當(dāng)你為一個(gè)窗體類創(chuàng)建多個(gè)實(shí)例的時(shí)候,你會(huì)陷入麻煩當(dāng)中。 ? ?
? ?
? 規(guī)則8:盡量避免在其他的窗體中使用Form1(Seldom ? Use ? Form1 ? In ? Other ? Forms ? ) ? ?
? 即使在其他窗體的代碼中,你也應(yīng)該盡量避免直接使用全局變量,如Form1.定義一些局部變量或者私有域供其他窗體使用會(huì)比直接調(diào)用全局變量要好。 ? ?
? 例如,程序的主窗體能夠?yàn)閷?duì)話框定義一個(gè)私有域。很顯然,如果你計(jì)劃為一個(gè)派生窗體創(chuàng)建多個(gè)實(shí)例,這條規(guī)則將是十分有用。你可以在主窗體的代碼范圍內(nèi)保持一份清單,也可以更簡(jiǎn)單地使用全局Sreen對(duì)象的窗體數(shù)組。 ? ?
? ?
? 規(guī)則9:移除Form1(Remove ? Form1) ? ?
? 事實(shí)上,我的建議是在你的程序中移除Delphi自動(dòng)創(chuàng)建的全局窗體對(duì)象。即使你禁止了窗體的自動(dòng)添加功能,這也有可能是必要的,因?yàn)樵贒elphi隨后仍然可能添加這樣的窗體。我給你的建議是應(yīng)該盡量避免使用全局窗體對(duì)象。 ? ?
? 我認(rèn)為對(duì)于Delphi新手而言,移除全局窗體對(duì)象是十分有用的,這樣他們不至于對(duì)類和全局對(duì)象兩者的關(guān)系感到疑惑。事實(shí)上,在全局窗體對(duì)象被移除后,所有與它有關(guān)的代碼都會(huì)產(chǎn)生錯(cuò)誤。 ?
? ?
? 問題點(diǎn)數(shù):0、回復(fù)次數(shù):112Top

1 樓ZyxIp(絕望中...)回復(fù)于 2003-09-02 14:28:22 得分 0

規(guī)則10:添加窗體屬性(Add ? Form ? Properties) ? ?
? 正如我已經(jīng)提到過的,當(dāng)你需要為你的窗體添加數(shù)據(jù)時(shí),請(qǐng)?zhí)砑右粋€(gè)私有域。如果你需要訪問其他類的數(shù)據(jù),可以為你的窗體添加屬性。使用這種方法你就能夠改變當(dāng)前窗體的代碼和數(shù)據(jù)(包含在它的用戶界面中)而不必改變其他窗體或類的代碼。 ? ?
? 你還應(yīng)該使用屬性或是方法來初始化派生窗體或是對(duì)話框,或是訪問他們的最終狀態(tài)。正如我前文所說的,你應(yīng)該使用構(gòu)造器來完成初始化工作 ? ?
? ?
? 規(guī)則11:顯示組件屬性(Expose ? Components ? Properties) ? ?
? 當(dāng)你需要訪問其他窗體的狀態(tài)時(shí),你不應(yīng)該直接訪問它的組件。因?yàn)檫@樣會(huì)將其他窗體或其它類的代碼和用戶界面結(jié)合在一起,而用戶界面往往是一個(gè)應(yīng)用程序中最容易發(fā)生改變的部分。最好的方法是,為你需要訪問的組件屬性定義一個(gè)窗體屬性。要實(shí)現(xiàn)這一點(diǎn),可以通過讀取組件狀態(tài)的Get方法和設(shè)置組件狀態(tài)的Set方法實(shí)現(xiàn)。 ? ?
? 假如你現(xiàn)在需要改變用戶界面,用另外一個(gè)組件替換現(xiàn)有的組件,那么你只需做的是修改與這個(gè)組件屬性相關(guān)的Get方法和Set方法,而不必查找,修改所有引用這個(gè)組件的窗體和類的源碼。詳細(xì)實(shí)現(xiàn)方法請(qǐng)參見下面的代碼: ? ?
? private ? ?
? function ? GetText:String; ? ?
? procedure ? SetText(const ? Value:String); ? ?
? public ? ?
? property ? Text:String; ? ?
? read ? GetText ? write ? SetText; ? ?
? function ? TformDialog.GetText:String; ? ?
? begin ? ?
? Result:=Edit1.Text; ? ?
? end; ? ?
? procedure ? TformDialog.SetText(const ? Value:String); ? ?
? begin ? ?
? Edit1.Text;=Value; ? ?
? end; ? ?
? ?
? 規(guī)則12:屬性數(shù)組(Array ? Properties) ? ?
? 如果你需要處理窗體中的一系列變量,你可以定義一個(gè)屬性數(shù)組。如果這些變量是一些對(duì)于窗體很重要的信息,你還可以把他們定義成窗體默認(rèn)的屬性數(shù)組,這樣你就可以直接使用SpecialForm[3]來訪問他們的值了。 ? ?
? 下面的代碼顯示了如何將一個(gè)listbox組件的項(xiàng)目定義成窗體默認(rèn)的屬性數(shù)組。 ? ?
? type ? ?
? TformDialog ? =class(TForm) ? ?
? private ? ?
? listItems:TlistBox; ? ?
? function ? GetItems(Index:Integer):String; ? ?
? procedure ? SetItems(Index:Integer:const ? Value:String); ? ?
? public ? ?
? property ? Items[Index:Integer]:string; ? ?
? end; ? ?
? function ? TFormDialog.GetItems(Index:Integer):string; ? ?
? begin ? ?
? if ? Index ? >=ListItems.Items.Count ? then ? ?
? raise ? Exception.Create(‘TformDialog:Out ? of ? Range’); ? ?
? Result:=ListItems.Items[Index]; ? ?
? end; ? ?
? procedure ? TformDialog.SetItems(Index:Integer;const ? alue:string); ? ?
? begin ? ?
? if ? Index ? >=ListItems.Items.Count ? then ? ?
? raise ? Exception.Create(‘TformDialog:Out ? of ? Range’); ? ?
? ListItems.Items[Index]:=Value; ? ?
? end; ? ?
? ?
? 規(guī)則13:使用屬性的附加作用(Use ? Side-Effects ? In ? Properties) ? ?
? 請(qǐng)記住:使用屬性而不是訪問全局變量(參見規(guī)則10、11、12)的好處之一就是當(dāng)你設(shè)置或者讀取屬性的值時(shí),你還可能有意想不到的收獲。 ? ?
? 例如,你可以直接在窗體界面上拖拉組件,設(shè)置多個(gè)屬性的值,調(diào)用特殊方法,立即改變多個(gè)組件的狀態(tài),或者撤銷一個(gè)事件(如果需要的話)等等。 ? ?
? ?
? 規(guī)則14:隱藏組件(Hide ? Components) ? ?
? 我經(jīng)常聽見那些面向?qū)ο缶幊痰目駸嶙非笳弑г笵elphi窗體中包含一些在published部分聲明的組件,這是和面向?qū)ο笏枷氲姆庋b性原理不相符合的。他們確實(shí)提出了一個(gè)重要的議題,但是他們中的大多數(shù)人都沒有意識(shí)到解決方法其實(shí)就在他們手邊,完全不用重寫Delphi代碼,也不用轉(zhuǎn)向其他語言。 ? ?
? Delphi向窗體中添加的組件參照可以被移到private部分,使得其他窗體不能訪問他們。如果你這樣做,你就有必要設(shè)置一些指向組件的窗體屬性(請(qǐng)參見規(guī)則11),并且使用它們來訪問組件的狀態(tài)。 ? ?
? Delphi將所有的這些組件都放在published部分,這是因?yàn)槭褂眠@種方式能夠保證這些域一定是在.DFM文件中創(chuàng)建的組件。當(dāng)你改變一個(gè)組件的名稱時(shí),VCL能夠自動(dòng)地將這個(gè)組件對(duì)象與它在窗體中的參照關(guān)聯(lián)起來。因?yàn)閐elphi使用RTTI和Tobject方法來實(shí)現(xiàn)這種功能,所以如果想要使用這種自動(dòng)實(shí)現(xiàn)功能,就必須把參照放置在published部分(這也正是為什么delphi將所有的組件都放在published部分的緣故)。 ? ?
? 如果你想知道的更詳細(xì)一點(diǎn),可以參看下面的代碼: ? ?
? ?
? procedure ? Tcomponent.SetReference(Enable:Boolean); ? ?
? var ? ?
? Field:^Tcomponent; ? ?
? begin ? ?
? If ? Fowner<> ? nil ? then ? begin ? ?
? Field:=Fowner.FieldAddress(Fname); ? ?
? If ? Field<>nil ? then ? ?
? Field^:=Self ? ?
? else ? ?
? Field^:=nil; ? ?
? end; ? ?
? end; ? ?
? ?
? 上面的代碼是Tcomponent類的SetReference方法,這個(gè)方法可以被InserComponent,RemoveComponent和SetName等方法調(diào)用。 ? ?
? 當(dāng)你理解了這一點(diǎn)后,你應(yīng)該不難想到如果你將組件參照從published部分移到了private段,你將失去VCL的自動(dòng)關(guān)聯(lián)功能。為了解決這個(gè)問題,你可以通過在窗體的OnCreate事件中添加如下代碼解決: ? ?
? Edit1:=FindComponent(‘Edit1’) ? as ? Tedit; ? ?
? 你接下來應(yīng)該做的就是在系統(tǒng)中注冊(cè)這些組件類,當(dāng)你為他們注冊(cè)過后就能使RTTI包含在編譯程序中并且能夠被系統(tǒng)所使用。當(dāng)你將這些類型的組件參照移到private部分時(shí),對(duì)于每一個(gè)組件類,你只需為他們注冊(cè)一次。即使為他們注冊(cè)不是一定必要的時(shí)候,你也可以這樣做,因?yàn)閷?duì)于RegisterClasses的額外調(diào)用有益無害。通常你應(yīng)該在單元中負(fù)責(zé)生成窗體的初始化部分添加以下的代碼: ? ?
? RegisterClass([TEdit]); ? ?
? ?
? 規(guī)則15:面向?qū)ο缶幊痰拇绑w向?qū)?#xff08;The ? OOP ? Form ? Wizard) ? ?
? 為每一個(gè)窗體的每一個(gè)組件重復(fù)上述兩個(gè)操作不僅十分的煩人,而且相當(dāng)?shù)睦速M(fèi)時(shí)間。為了避免額外的負(fù)擔(dān),我已經(jīng)為此寫了一個(gè)簡(jiǎn)單的向?qū)С绦颉_@個(gè)程序?qū)?huì)生成一些可以完成以上兩步工作的代碼,你需要做的僅僅是做幾次復(fù)制和粘貼就行了。 ? ?
? 遺憾的是這個(gè)向?qū)С绦虿荒茏詣?dòng)將代碼放置到單元中合適的地方,我目前正在修改這個(gè)向?qū)С绦?#xff0c;希望能實(shí)現(xiàn)這個(gè)功能。你可以到我的網(wǎng)站(www.marcocantu.com)查找更加完善的程序。 ? ?
? ?
? 規(guī)則16:可視化窗體繼承(Visual ? Form ? Inheritance) ? ?
? 如果應(yīng)用得當(dāng),這將是一個(gè)強(qiáng)大的工具。根據(jù)我的經(jīng)驗(yàn),你所開發(fā)的項(xiàng)目越大,越能體現(xiàn)它的價(jià)值。在一個(gè)復(fù)雜的程序中,你可以使用窗體的不同等級(jí)關(guān)系來處理一組相關(guān)窗體的多態(tài)性(polymorphism)。 ? ?
? 可視化窗體繼承允許你共享多個(gè)窗體的一些公共的動(dòng)作:你可以使用共享的方法,公用的屬性,甚至是事件處理程序,組件,組件屬性,組件事件處理方法等等。 ? ?
? ?
? 規(guī)則17:限制保護(hù)域數(shù)據(jù)的使用(Limit ? Protected ? Data) ? ?
? 當(dāng)創(chuàng)建一些具有不同分級(jí)體系的類時(shí),一些程序員趨向于主要使用保護(hù)域,因?yàn)樗接袛?shù)據(jù)不能被子類訪問。我不能說這沒有其合理性,但是這肯定是和封裝性不相容和的。保護(hù)數(shù)據(jù)的實(shí)現(xiàn)能夠被所有繼承的窗體所共享,而且一旦這些數(shù)據(jù)的原始定義發(fā)生改變,你必須更改所有的相關(guān)部分。 ? ?
? 請(qǐng)注意,如果你遵循隱藏組件這樣一條規(guī)則(Rule ? 14),繼承窗體就不可能訪問基類的私有組件。在一個(gè)繼承窗體中,類似Edit1.Text:=’’的代碼就不會(huì)被編譯。雖然這是相當(dāng)?shù)牟环奖?#xff0c;但是至少在理論上這是值得肯定的事情,而不是否定的。如果你感覺到實(shí)現(xiàn)封裝性是最主要,最需要的,就請(qǐng)將這些組件參照放在基類的私有段。 ? ?
? ?
? 規(guī)則18:保護(hù)域中的訪問方法(Protected ? Access ? Methods) ? ?
? 在基類中將組件參照放置在私有域中,而為這些組件添加一些訪問函數(shù)來得到他們的屬性,這將是一種更好的方法。如果這些訪問函數(shù)僅僅在這些類內(nèi)部使用而且不是類接口的一部分,你應(yīng)該在保護(hù)域聲明他們。例如Rule ? 11中描述過的GetText和SetText方法就可以聲明成protected,并且我們可以通過調(diào)用SetText(’’)來編輯文本。 ? ?
? 事實(shí)上,當(dāng)一個(gè)方法被鏡像到一個(gè)屬性時(shí),我們可以簡(jiǎn)單地采用如下代碼就可以達(dá)到編輯文本地目的:Text:=’’; ? ?
? ?
? 規(guī)則19:保護(hù)域中的虛擬方法(Protected ? Virtual ? Methods) ? ?
? 實(shí)現(xiàn)一個(gè)靈活的分級(jí)制度的另一個(gè)關(guān)鍵點(diǎn)是定義一些你可以從外部類調(diào)用的虛擬方法來得到多態(tài)性。如果這個(gè)方法使用得當(dāng),將會(huì)很少出現(xiàn)其他公共的方法調(diào)用保護(hù)域中的虛擬方法的情況。這是一個(gè)重要的技巧,因?yàn)槟憧梢远ㄖ婆缮惖奶摂M方法,來修改對(duì)象的動(dòng)作。 ? ?
? ?
? 規(guī)則20:用于屬性的虛擬方法(Virtual ? Methods ? For ? Properties) ? ?
? 即使是訪問屬性的方法也能定義成virtual,這樣派生類就能改變屬性的動(dòng)作而不必重定義他們。雖然這種方法在VCL當(dāng)中很少使用,但是它確實(shí)十分靈活、強(qiáng)大。為了實(shí)現(xiàn)這一點(diǎn),僅僅需要將Rule ? 11當(dāng)中的Get ? 和Set ? 方法定義成Virtual。基類的代碼如下所示: ? ?
? type ? ?
? TformDialog ? = ? class ? ( ? TForm) ? ?
? Procedure ? FormCreate(Sender:Tobject); ? ?
? Private ? ?
? Edit1:Tedit; ? ?
? Protected ? ?
? function ? GetText:String;virtual; ? ?
? procedure ? SetText(const ? Value:String);virtual; ? ?
? public ? ?
? constructor ? Create(Text ? :String):reintroduce;overload; ? ?
? property ? Text:String ? read ? GetText ? write ? SetText; ? ?
? end; ? ?
? ?
? 在繼承窗體中,你可以添加一些額外的動(dòng)作來重載虛擬方法SetText: ? ?
? procedure ? TformInherit.SetText(const ? Value:String); ? ?
? begin ? ?
? inherited ? SetText(Value); ? ?
? if ? Value=’’ ? then ? ?
? Button1.Enabled:=False; ? ?
? end;

總結(jié)

以上是生活随笔為你收集整理的▼▲Delphi面向对象编程的20条规则的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。