【正文】
Java 采取的這種關(guān)鍵字保留機制其實經(jīng)常讓人摸不著頭腦,很難斷定以后會發(fā)生什么事情。 參數(shù)化類型是 C++一個重要的組成部分,這部分是 C++沒有單根結(jié)構(gòu)的緣故。 下溯造型和運行期檢查都要求花額外的時間來運行程序,而且程序員必須付出額外的精力。但我們不知道一個 Object 到底是 Circle 還是 Shape,所以很難保證下溯造型的安全進(jìn)行,除非確切地知道自己要操作的是什么。但這一次不是在分級結(jié)構(gòu)中上溯造型成一種更 “ 通用 ” 的類型。 為使用這樣的一個集合,只需添加指向它的對象句柄即可,以后可以通過句柄重新使用對象。 Java 提供了這樣的 一個庫,盡管它在 Java 和 中都顯得非常有限( Java 的集合庫則無疑是一個杰作)。 由于運行期的類型信息肯定存在于所有對象中,所以永遠(yuǎn)不會遇到判斷不出一個對象的類型的情況。一個單根結(jié)構(gòu),加上所有對象都在內(nèi)存堆中創(chuàng)建,可以極大簡化參數(shù)的傳遞(這在 C++里是一個復(fù)雜的概念)。為得到 C++額外的 “ 靈活性 ” ,付出這樣的代價值得 嗎?當(dāng)然,如果真的需要 —— 如果早已是 C 專家,如果對 C 有難舍的情結(jié) —— 那么就真的很值得。從向后兼容的角度看,這一方案可與 C 模型更好地配合,而且可以認(rèn)為它的限制更少一些。在 Java 中(與其他幾乎所有 OOP語言一樣),對這個問題的答案都是肯定的,而且這個終級基礎(chǔ)類的名字很簡單,就是一個 “Object” 。如果在一個編程環(huán)境中工作,它由于其他因素(比如在 Windows下運行,或者由垃圾 收集器帶來了開銷)產(chǎn)生了內(nèi)在的開銷,那么矢量和鏈接列表之間在系統(tǒng)開銷上的差異就或許不是一個大問題。最后調(diào)整性能的時候,再根據(jù)情況把它換成矢量。而且假設(shè)某個元素位于列表較遠(yuǎn)的地方,找到它所需的時間也會長許多。它們都屬于簡單的序列,擁有完全一致的接口和外部行為。堆棧的接口與行為與隊列的不同,而隊列的接口與行為又與一個集( Set)或列表的不同。通過對它的操縱,應(yīng)該能解決自己的問題。這樣一來,我們就可以靈活地改變基礎(chǔ)數(shù)據(jù),不會對程序里的代碼造成干擾。作為一個類,它也提供了一級抽象。如果是一個數(shù)組形式的實體,比如一個矢量( Vector),那么也許能用索引運算符或函數(shù)。 所有集合都提供了相應(yīng)的讀寫功能。在某些庫中,一個常規(guī)集合便可滿足人們的大多數(shù)要求;而在另一些庫中(特別是 C++的庫),則面向不同的需求提供了不同類型的集合。在 C++中,它們是以 “ 標(biāo)準(zhǔn)模板庫 ” ( STL)的形式提供的。在需要的時候,集合會自動擴充自己,以便適應(yīng)我們在其中置入的任何東西。用于解決特定問題的新型對象容納了指向其他對象的句柄。 本節(jié)剩下的部分將討論操縱對象時要考慮的另一些因素。程序員可用兩種方法來破壞一個對象:用程序化的方式?jīng)Q定何時破壞對象,或者利用由運行環(huán)境提供的一種 “ 垃圾收集器 ” 特性,自動尋找那些不再使用的對象,并將其清除。 C++允許我們決定是在寫程序時創(chuàng)建對象,還是在運行期間創(chuàng)建,這種控制方法更加靈活。若需一個新對 象,只需在需要它的時候在內(nèi)存堆里簡單地創(chuàng)建它即可。如果要解決的是一個較常規(guī)的問題,如計算機輔助設(shè)計、倉儲管理或者空中交通控制,這一方法就顯得太局限了。為獲得最快的運行速度,存儲以及存在時間可在編寫程序時決定,只需將對象放置在堆棧(有時也叫作自動或定域變量)或者靜態(tài)存儲區(qū)域即可。本節(jié)將就這些問題進(jìn)行探討。s another issue, however, and that39。 外文資料 Object landscapes and lifetimes Technically, OOP is just about abstract data typing, inheritance, and polymorphism, but other issues can be at least as important. The remainder of this section will cover these issues. One of the most important factors is the way objects are created and destroyed. Where is the data for an object and how is the lifetime of the object controlled? There are different philosophies at work here. C++ takes the approach that control of efficiency is the most important issue, so it gives the programmer a choice. For maximum runtime speed, the storage and lifetime can be determined while the program is being written, by placing the objects on the stack (these are sometimes called automatic or scoped variables) or in the static storage area. This places a priority on the speed of storage allocation and release, and control of these can be very valuable in some situations. However, you sacrifice flexibility because you must know the exact quantity, lifetime, and type of objects w hile you39。s the lifetime of an object. With languages that allow objects to be created on the stack, the piler determines how long the object lasts and can automatically destroy it. However, if you create it on the heap the piler has no knowledge of its lifetime. In a language like C++, you must determine programmatically when to destroy the object, which can lead to memory leaks if you don’t do it correctly (and this is a mon problem in C++ programs). Java provides a feature called a garbage collector that automatically discovers when an object is no longer in use and destroys it. A garbage collector is much more convenient because it reduces the number of issues that you must track and the code you must write. More important, the garbage collector provides a much higher level of insurance against the insidious problem of memory leaks (which has brought many a C++ project to its knees). The rest of this section looks at additional factors concerning object lifetimes and landscapes. 1 Collections and iterators If you don’t know how many objects you’re going to need to solve a particular problem, or how long they will last, you also don’t know how to store those objects. How can you know how much space to create for those objects? You can’t, since that information isn’t known until runtime. The solution to most problems in objectoriented design seems flippant: you create another type