11.4 總結(jié)
利用RTTI可根據(jù)一個匿名的基礎(chǔ)類句柄調(diào)查出類型信息课锌。但正是由于這個原因,新手們極易誤用它祈秕,因為有些時候多形性方法便足夠了渺贤。對那些以前習慣程序化編程的人來說雏胃,極易將他們的程序組織成一系列switch語句。他們可能用RTTI做到這一點癣亚,從而在代碼開發(fā)和維護中損失多形性技術(shù)的重要價值丑掺。Java的要求是讓我們盡可能地采用多形性,只有在極特別的情況下才使用RTTI述雾。
但為了利用多形性街州,要求我們擁有對基礎(chǔ)類定義的控制權(quán),因為有些時候在程序范圍之內(nèi)玻孟,可能發(fā)現(xiàn)基礎(chǔ)類并未包括我們想要的方法唆缴。若基礎(chǔ)類來自一個庫,或者由別的什么東西控制著黍翎,RTTI便是一種很好的解決方案:可繼承一個新類型面徽,然后添加自己的額外方法。在代碼的其他地方匣掸,可以偵測自己的特定類型趟紊,并調(diào)用那個特殊的方法。這樣做不會破壞多形性以及程序的擴展能力碰酝,因為新類型的添加不要求查找程序中的switch語句霎匈。但在需要新特性的主體中添加新代碼時,就必須用RTTI偵測自己特定的類型送爸。
從某個特定類的利益的角度出發(fā)铛嘱,在基礎(chǔ)類里加入一個特性后,可能意味著從那個基礎(chǔ)類衍生的其他所有類都必須獲得一些無意義的“雞肋”袭厂。這使得接口變得含義模糊墨吓。若有人從那個基礎(chǔ)類繼承,且必須覆蓋抽象方法纹磺,這一現(xiàn)象便會使他們陷入困擾帖烘。比如現(xiàn)在用一個類結(jié)構(gòu)來表示樂器(Instrument)。假定我們想清潔管弦樂隊中所有適當樂器的通氣音栓(Spit Valve)橄杨,此時的一個辦法是在基礎(chǔ)類Instrument中置入一個ClearSpitValve()方法秘症。但這樣做會造成一個誤區(qū),因為它暗示著打擊樂器和電子樂器中也有音栓讥珍。針對這種情況历极,RTTI提供了一個更合理的解決方案窄瘟,可將方法置入特定的類中(此時是Wind衷佃,即“通氣口”)——這樣做是可行的。但事實上一種更合理的方案是將prepareInstrument()置入基礎(chǔ)類中蹄葱。初學者剛開始時往往看不到這一點氏义,一般會認定自己必須使用RTTI锄列。
最后,RTTI有時能解決效率問題惯悠。若代碼大量運用了多形性邻邮,但其中的一個對象在執(zhí)行效率上很有問題,便可用RTTI找出那個類型克婶,然后寫一段適當?shù)拇a筒严,改進其效率。