在JBuilder中通過重構將值域、方法在類的繼承體系中上推下移,是非常容易的操作。這了說明這種重構功能,我們先來看下面的類繼承體系:
圖15 類的繼承類圖
Animal類是Cat和Horse和父類,Animal中包含了兩個值域和一個方法。可以將Animal中的值域有選擇地下移到某個子類中。此外,還可以為Animal提煉超類和接口。
1、搬遷方法
打開Animal.java並將光標定位到howl()方法處,通過Ctrl+Shift+R->Push Down Method調出下移方法對話框:
圖16 下移方法
·Method:下移的方法。
·Keep as abstract in current class:表示在下移方法的同時將類轉為抽象類。
·Selected subclasses:列出當前類的所有子類,默認情況下方法將下移到所有子類中,我們取消Cat,僅將howl()下移到Horse中。
方法howl()中引用到Animal類的一個私有變量private int volume,在下移howl()後,該變量變為protected int volume。
上推和下移是相反的操作,負責將子類中的方法推到父類中去。保存並重新編譯工程,打開Horse.java將光標置到howl()方法處:Ctrl+Shift+R->Pull Up Method調出上推的對話框:
圖17
上推方法
如果需上推的方法引用到了類中的其他方法,這些被引用的方法列在Select dependent members to moves列表中,一般情況下你需要將這些被引用的方法一起上移到父類中。
面向對象的一個重要特性即是子類共享父類的代碼,所以當你發現子類的方法或值域是共享性的代碼時,你就需要著手將這些代碼推到父類中去了,這樣代碼的復用性將得到提升。
2、搬遷值域
Animal類中有兩個值域:
1. protected int weight ;
2. protected int volume = weight ;
我們希望將volume下移到子類Cat中,光標定位到volume處:Ctrl+Shift+R>Push Down Field調出下移值域的對話框:
圖18 下移值域
·Field:需下移的值域。
·Select subclasses:當前類的子類。在默認情況下,值域下移到所有的子類中,可以通過子類前的復選框作出選擇,這裡我們去除Horse類前的勾選,即僅下移到Cat中。
·Select dependent members to move:和下移值域相關的所有值域,JBuilder通過下移值域右邊的賦值語句找出所有關聯的值域,通過關聯值域前的復選框決定是否需要一起下移到子類。默認情況下,JBuilder將關聯的屬性weight隨volume一起下移。
按OK後完成下移。編譯工程,打開Horse.java,我們執行下移值域的反操作:上推值域到Animal類中。
光標定位在Horse.java的volume值域處:Ctrl+Shift+R->Pull Up Field調出上推值域對話框,如下圖所示:
圖19
上推值域
點擊OK後,volume值域被上推到Horse父類Animal中。
提示:
遺憾的是,JBuilder上推值域並不會像下移值域一樣列出所有相關值域,只是簡單的將值域聲明代碼行上推到父類中。所以如果在值域的定義代碼行中引用了類中其它的值域,在上推到父為中時,將會發生語法錯誤,需要你手工解決。
3、提煉超類
幾個類具有相同的功能時,就需要提煉出一個超類出來。如隨著需求的變化,我們不但需要對四腳野獸(Animal)予以關注,還需要對鳥類(Bird)投注關懷,那麼在Bird和Animal之上抽象出一個Creature類出來是再適合不過的了。
打開Animal.java,光標移至類名稱Animal處:Ctrl+Shift+R->Introduce Superclass for “Animal” 調出提煉超類的對話框,如下圖所示:
圖20 提煉超類對話框
在Superclass name中指定超類名Creature,在Package中指定超類所在的包名,默認為當前類所在的包,按OK按鈕,JBuilder創建Creature超類,並使Animal類繼承這個超類:
代碼清單 7 Creature超類
1. package myrefactor ;
2.
3. public class Creature
4. {
5. public Creature()
6. {
7. }
8. }
Animal代碼做如下調整
代碼清單 8 提煉超類
1. package myrefactor ;
2.
3. public class Animal extends Creature
4. {
5. …
6. }
由於Creature生成後並未編譯,所以Animal類在編輯器中會提示語法錯誤, 出現在控制槽上。你可以通過重構信息窗口的 按鈕編譯重構相關的類以消除這個語法錯誤。本文後續內容還會碰到相似的情況,解決方法相同,將不再贅述。
4、提煉接口
假設我們需要為動物定義一些共同的習性,可以將類的若干方法提煉出來,用一個接口來表達。打開Animal.java,將光標移到類名Animal處:Ctrl+Shift+R->Extract Interface from Class “Animal”調出提煉接口對話框,如下所示:
圖21 提煉接口對話框
·Interface name:接口名稱,填入Habitable。
·Package:包名,接受默認值。
·Available methods:JBuilder將Animal類中所有的public方法列在該列表中,你可以選擇需要將哪些方法抽取到接口中。
點擊OK完成Habitable接口的提煉。JBuilder創建Habitable接口,並使Animal實現這個接口。
代碼清單 9 Habitable接口
1. package myrefactor ;
2.
3. public interface Habitable
4. {
5. public void howl() ;
6. }
Animal類調整如下:
代碼清單 10 提煉接口
1. package myrefactor ;
2. public class Animal extends Creature implements Habitable
3. {
4. …
5. }
假設你僅希望將類中的某個方法提煉到一個接口中,你可以直接將光標移至方法名處:Ctrl+Shift+R->Extract to Interface Method更直接地完成這個操作。