在 Java 語言的 Jam 擴(kuò)展中,mixin 的超類類型沒有名稱;我們就不能在 mixin 主體中引用它。這一限制會(huì)迅速引起一連串各種其它問題。例如,在 Jam 中,禁止程序員將 this 作為參數(shù)傳遞給方法;無法對(duì)這樣的調(diào)用進(jìn)行類型檢查。這一限制的影響極大,因?yàn)樵S多最常見的設(shè)計(jì)模式都要依靠于能夠?qū)?this 作為參數(shù)傳遞。
請(qǐng)考慮訪問者模式,其中用 for 方法為復(fù)合層次結(jié)構(gòu)中的每個(gè)類都定義了訪問者類。通常被訪問的類包含 accept 方法,它采用訪問者并傳遞 this 來調(diào)用該訪問者的方法。因此,在 Jam 中,訪問者模式不能和 mixin 一起使用。
將 mixin 明確表述為泛型類,我們就始終有父類的句柄,它是該類繼續(xù)的類型參數(shù)。例如,我們可以將 Scrollable 的父類引用為類型 T。其結(jié)果是,在答應(yīng)將 this 作為類型參數(shù)傳遞時(shí)沒有任何根本性的困難。
解決這一問題的各種方案與我們上月第 3 部分中討論的針對(duì)檢查 new 表達(dá)式的類型參數(shù)所提出的解決方案完全一致,因?yàn)槌?jí)構(gòu)造函數(shù)調(diào)用和 new 表達(dá)式都引用了給定類的同一個(gè)類構(gòu)造函數(shù)。讓我們回顧一下這些解決方案:
需要一個(gè)不帶參數(shù)的(zeroary)構(gòu)造函數(shù),用于所有類型參數(shù)的實(shí)例化。 當(dāng)沒有匹配的構(gòu)造函數(shù)時(shí),拋出運(yùn)行時(shí)異常。 包含額外的類型參數(shù)注釋,告知我們這些實(shí)例化必須包含哪些構(gòu)造函數(shù)。 就如 new 表達(dá)式的情況,前兩個(gè)解決方案有嚴(yán)重缺陷。通常在類定義中包含不帶參數(shù)的構(gòu)造函數(shù)沒有任何意義。而且,當(dāng)不存在任何匹配的構(gòu)造函數(shù)時(shí)就拋出異常也不太理想。究竟靜態(tài)類型檢查主要是嚴(yán)格防止那種異常。
第三種解決方案可能有點(diǎn)繁瑣,但是它有許多優(yōu)點(diǎn)。注釋類型參數(shù),其中包括所有實(shí)例化都必須擁有的構(gòu)造函數(shù)集。這些注釋確切地告知我們針對(duì)類型參數(shù),我們可以可靠地調(diào)用什么樣的構(gòu)造函數(shù)。因此,當(dāng)類型參數(shù) T 用作泛型類的超類時(shí),T 的注釋確切地告知我們可以調(diào)用哪些超級(jí)構(gòu)造函數(shù)。假如 T 不包含注釋,那么類型檢查器會(huì)禁止它用作超類。