溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java代碼復用的三種常用方式:繼承、組合和代理

發布時間:2020-07-24 20:03:02 來源:網絡 閱讀:94 作者:沉默王二 欄目:編程語言

復用代碼是 Java 眾多引人注目的功能之一。這句話很通順,沒什么問題,但問題在于很多人并不清楚“復用”是什么。就好像我說“沉默王二是一個有趣的程序員”,唉,沉默王二是誰?

我們需要來給“復用”下一個定義。復用,說白了就是重復使用。

舉個例子,很多名人說了很多名言,我們在說話、寫作的時候,就經常有意無意的重復這些名言。比如說我,就特別喜歡重復使用王小波的那句名言:“從話語中,你很少能學到人性,從沉默中卻能。假如還想學得更多,那就要繼續一聲不吭 ?!?/p>

上面這個例子,只能說是“復用”的一種低級的應用,其實就是復制粘貼了。還有高級的復用方式嗎?

有,當然有。Java 作為一種優秀的面向對象設計的語言,在復用的應用上就高級得多了。

01、繼承

最常見的復用方法就是繼承——使用 extends 關鍵字在基類的基礎上創建新類,新類可以直接復用基類的非 private 的屬性和方法;就像程序清單1-1那樣。

程序清單1-1:

public?class?Wangxiaosan?extends?Wangsan?{
????public?Wangxiaosan()?{
????????System.out.println("我是新類王小三");

????????setName("王老三");

????????System.out.println(getName());
????}

????public?static?void?main(String[]?args)?{
????????new?Wangxiaosan();
????}
}

class?Wangsan?{
????private?String?name;

????Wangsan()?{
????????System.out.println("我是基類王三");
????}

????public?String?getName()?{
????????return?name;
????}

????public?void?setName(String?name)?{
????????this.name?=?name;
????}
}

從程序清單 1-1 中我們可以看得出,getName() 和 setName() 方法雖然是在基類 Wangsan 中創建的,但可以在新類 Wangxiaosan 中使用,代碼的復用工作就這樣輕松地完成了。

02、組合

另外一種常見的復用方法就是組合——在新類中創建已有類的對象,通過該對象來調用已有類中的非 private 的屬性和方法;就像程序清單2-1那樣。

程序清單2-1:

public?class?Tongxiangyu?{
????private?Baizhantang?boyFriend?=?new?Baizhantang();

????public?Tongxiangyu()?{
????????System.out.println("我是同??蜅5恼乒褓∠嬗?);

????????boyFriend.pointHand("郭芙蓉");
????}

????public?static?void?main(String[]?args)?{
????????new?Tongxiangyu();
????}
}

class?Baizhantang?{
????Baizhantang()?{
????????System.out.println("我是退隱江湖的盜圣白展堂");
????}

????public?void?pointHand(String?name)?{
????????System.out.println("那誰"?+?name?+?",準備一下——葵花點穴手");
????}
}

從程序清單 2-1 中我們可以看得出,葵花點穴手雖然是白展堂的絕技,但作為佟掌柜的男朋友,佟掌柜要展堂點個穴,展堂也是不敢推辭的。你看,佟掌柜雖然是個弱女子,但自從有了展堂這個武功數一數二的男朋友,再沒有誰敢不聽話啊——厲害的組合啊。

需要注意的是,如何在繼承和組合之間做出選擇呢?

如果新類和已有類需要具有一些相似的方法和屬性時,就采用繼承的形式;如果新類只是為了借用已有類的一些方法和屬性時,而兩者沒有很多相似之處時就需要采用組合的形式。

03、 代理

還有一種復用方法是代理——在新類中創建代理,通過代理來操作已有類的非 private 的屬性和方法;就像程序清單 3-1 那樣。

程序清單3-1:

public?class?Member?{
????public?static?void?main(String[]?args)?{
????????Proxy?proxy?=?new?Proxy();
????????System.out.println("代理說一個藥丸十五塊");
????????proxy.buy(15);
????}
}

class?Proxy?{
????private?Shop?shop?=?new?Shop();

????public?void?buy(int?money)?{
????????System.out.println("一個藥丸十五塊");
????????shop.sale(money?-?5);
????}
}

class?Shop?{
????public?void?sale(int?money)?{
????????System.out.println("一個藥丸十塊錢");
????}
}

從程序清單 3-1 中我們可以看得出,代理的模式和組合有點類似,但又有差別——代理成功的隔開了新類(會員)和已有類(店鋪)的直接關系,使得已有類的方法不直接暴露在新類面前(組合的方式會將已有類的非private的方法和屬性直接暴露在新類中);與此同時,代理拿到了足夠的好處。

04、final

作為代碼的生產者來說,我們有時候希望代碼被復用,有的時候又希望代碼不被復用。當我們不想代碼被復用時,final 關鍵字就派上用場了。final 這個關鍵字很形象,它本身就說明了一切——最后的,最終的;決定性的;不可更改的。

使用 final 的場景有三種,分別是數據、方法和類。我們來稍作說明。

1)final 數據

最常見的 final 數據就是常量了,例如:

public?class?Consts?{
????public?static?final?String?CMOWER?=?"沉默王二";
}

對于常量來說,它對于整個應用內的所有類都是可見的,因此是 public 的;它可以直接通過類名.常量名訪問,所以是 static 的;它是不可修改的,因此是 final 的。

另外一種常見的 final 數據就是參數了,參照程序清單 4-1。

程序清單4-1:

public?class?Cmower?{

????public?void?write(final?String?content)?{
????????//?content?+=?"猶未雪";?//?final修飾的參數是無法在方法內部被再次修改的
????????System.out.println(content);
????}

????public?void?write1(String?content)?{
????????content?+=?"猶未雪";
????????System.out.println(content);
????}

????public?static?void?main(String[]?args)?{
????????Cmower?cmower?=?new?Cmower();
????????cmower.write("精忠報國");
????????cmower.write1("靖康恥");
????}
}

2)final 方法

在 Java 類中,所有的 private 方法都隱式地指定為 final 的(也就是說,如果你在 private 方法上加上 final 修飾符,其實是沒啥意義的)。在介紹繼承的時候,你應該注意到我強調的一句話,就是新類可以直接復用基類的非 private 的屬性和方法,也就是說 private 方法是無法被繼承者修改的,因為 private 方法是 final 的。

來看程序清單 4-2,你會發現 Wangsan 類型的 san 引用是不能調用 say(String words) 方法的,因為 private 方法是無法被繼承者修改的,盡管 Wangxiaosan 中重新定義了 say(String words) 方法。

程序清單4-2:

public?class?Wangxiaosan?extends?Wangsan?{
????public?Wangxiaosan()?{
????????say("吃中飯沒");
????}

????public?void?say(String?words)?{
????????System.out.println("王小三在說:"?+?words);
????}

????public?static?void?main(String[]?args)?{
????????Wangsan?san?=?new?Wangxiaosan();
????????//?san.say("吃晚餐沒");?//?無法訪問,并不會被覆蓋
????}
}

class?Wangsan?{
????public?Wangsan()?{
????????say("吃早飯沒");
????}

????private?void?say(String?words)?{
????????System.out.println("王三在說:"?+?words);
????}
}

3)final 類

當我們認為某個類就是最終的形態了,它很完美,不應該被繼承,就可以使用final關鍵字來修飾;參照程序清單 4-3。

程序清單 4-3:

//?無法繼承
public?class?Wangxiaosan?extends?Wangsan?{
}

final?class?Wangsan?{
????public?Wangsan()?{
????????System.out.println("我就是最終形態,別繼承我!");
????}
}

上一篇:Java 訪問權限控制:public、private、protected

下一篇:Java:多態乃幸福本源

微信搜索「沉默王二」公眾號,關注后回復「免費視頻」獲取 500G Java 高質量教學視頻(已分門別類)。


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女