第十九條:要么為繼承而設計并提供文檔說明,要么就禁止繼承

在前面一條中,我們已經知道了David寫了A類被Tom拿去繼承了,導致了A類的封裝性遭到了破壞,那么有沒有可能做點事情避免此事發生呢?第十九條孕育而生!David在創建A類的時候寫上文檔說明,說Al類不允許任何類來繼承,Tom看到后就不會這么做了,除非Tom喜歡寫獅山代碼,一上來不看別人別的文檔說明,一上來就操作猛如虎(這類人現實中其實挺多的)。

好的API應該描述一個給定的方法做了什么工作,而不是描述他是如何做到的。

那么,當你為了繼承而設計的類的時候,如何決定應該暴露那些受保護的成員呢?遺憾的是,并沒有神奇的法則可供你使用。唯一的方法就是測試。

要測試一個為繼承而設計的類,唯一的測試方法就是編寫子類。經驗表明,3個子類通常就足可以測試一個可擴展的類。

當設計一個可能被廣泛使用的用于繼承的類時,要意識到,我們對寫在文檔中的方法的自身使用情況,以及隱含在受保護的方法和字段的實現決策做出了永久性的承諾。這些承諾可能會使在隨后的版本中改進這個類的性能或功能變得困難,甚至不可能。因此,在發布之前必須通過編寫子類來測試。

還有些允許繼承的類必須遵守的限制。構造器不得直接或者間接調用可重寫的方法。違反這個規定,有可能導致程序失敗。超類的構造器會在子類的構造器之前運行,所以子類重寫的方法會在子類構造器之前被調用。

例子:

public class Super{//存在問題 構造器調用了一個可重寫的方法public Super() {overrideMe();}public void overrideMe(){}
}
public final class Sub extends Super{// 一個空的final字段,由構造器設置private final Date date;public Sub(){date=new Date();}//超類構造器調用的重寫方法@Overridepublic void overrideMe(){System.out.println(date);}public static void main(String[] args){Sub sub=new Sub();sub.overrideMe();}
}

結果:

Connected to the target VM, address: '127.0.0.1:51415', transport: 'socket'
null
Wed Jun 26 21:52:51 CST 2024
Disconnected from the target VM, address: '127.0.0.1:51415', transport: 'socket'Process finished with exit code 0

你可能會期待這個程序會打印出日期倆次,但是它第一次打印出的是null,因為overrideMe方法被Super構造器調用的時候,構造器Sub還沒有機會初始化Date域

在為了繼承而設計的類的時候,Cloneable和Serializable接口出現了特殊的困難。如果類是為了繼承而被設計的,無論實現這其中的那個接口通常都不是一個好主意,因為他們它一下實質性的負擔轉嫁到擴展這個類的程序員的身上。

如果你決定在一個為了繼承而設計的類中實現Cloneable或者Serializable接口,就應該意識到,因為clone和readObject方法在行為上非常類似于構造器,所以類似的限制規則也是使用的:無論是clone還是readObject,都不可以調用可覆蓋的方法,不管是以直接還是間接的方式。

如果你決定在一個為了繼承而設計的類中實現Serializable,并且該類有一個readResolve或者writeReplace方法,就必須使readResolve或者writeReplace成為受保護的方法,而不是私有的方法。

現在我們很清楚了,設計一個用于繼承的類需要付出巨大的努力,對類本身也是很大的限制。

解決這個問題的最佳方案是,對于并非為可以安全地子類化而設計并提供文檔說明的類,禁止對其子類化。

所有文章無條件開放,順手點個贊不為過吧!

? ? ? ? ? ? ? ? ? ? ? ?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/35829.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/35829.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/35829.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

node 實現導出, 在導出excel中包含圖片(附件)

如果想查看 node mySql 實現數據的導入導出,以及導入批量插入的sql語句,連接如下 node mySql 實現數據的導入導出,以及導入批量插入的sql語句-CSDN博客https://blog.csdn.net/snows_l/article/details/139998373 一、效果如圖: 二…

中介子方程三十四

XXFXXuXXWXXuXXdXXrXXαXXuXpXXKXηXiXXαXXiXηXKXXpXuXXαXXrXXdXXuXWXπXXWXeXyXeXbXπXpXXNXXqXeXXrXXαXXuXpXXKXηXiXXαXXiXηXKXXpXuXXαXXrXXeXqXXNXXpXπXbXeXyXeXWXXπXWXuXXdXXrXXαXXuXpXXKXηXiXXαXXiXηXKXXpXuXXαXXrXXdXXuXXWXXuXXFXXEXXyXXEXXrXXαXXuXpXXK…

paraview跨節點并行渲染

參考: https://cloud.tencent.com/developer/ask/sof/101483588 ParaView 支持使用其內置的網絡拓撲來進行跨節點的并行渲染。以下是一個簡單的步驟來設置和運行跨節點的并行渲染: 確保你的計算環境支持多節點計算,比如通過SSH、MPI或其他集…

阿里云擴容

官網:https://help.aliyun.com/zh/ecs/user-guide/extend-the-partitions-and-file-systems-of-disks-on-a-linux-instance?spm5176.ecs-console-storage_disk.help.dexternal.72d24df5QOL4ss 博客:http://t.csdnimg.cn/cUykr

Android APP通過View修改鼠標樣式

app view上修改鼠標樣式比較簡單,使用如下方法修改為自定義圖片: getWindow().getDecorView().setPointerIcon(PointerIcon.load(getResources(), R.drawable.pointer_spot_touch_icon)); 設置鼠標樣式setPointerIcon的調用棧 frameworks/base/core/jav…

C語言:流量控制

前言 流量控制可以讓發送端根據接收端的實際接受能力控制發送的數據量。它的具體操作是,接收端主機向發送端主機通知自己可以接收數據的大小,于是發送端會發送不會超過該大小的數據,該限制大小即為窗口大小,即窗口大小由接收端主…

【Linux詳解】進程的狀態 | 運行 阻塞 掛起 | 僵尸和孤兒狀態

目錄 操作系統中 運行狀態 阻塞狀態 進程狀態轉換 Linux系統中 查看進程狀態 深度睡眠狀態 T 暫停狀態 Z 僵尸狀態 孤兒狀態 文章手稿 xmind: 引言 介紹系統中的進程狀態及其管理方式。將通過結合操作系統原理和實際代碼示例,詳細說明進程的各種狀態、轉換…

鴻蒙開發Ability Kit(程序框架服務):【FA模型切換Stage模型指導】 app和deviceConfig的切換

app和deviceConfig的切換 為了便于開發者維護應用級別的屬性配置,Stage模型將config.json中的app和deviceConfig標簽提取到了app.json5中進行配置,并對部分標簽名稱進行了修改,具體差異見下表。 表1 配置文件app標簽差異對比 配置項FA模型…

Excel中的“點選輸入”——次級下拉列表創建

在Excel中,用“數據驗證”功能可以設置下拉列表,二級下拉列表需要設置公式。 (筆記模板由python腳本于2024年06月16日 18:36:37創建,本篇筆記適合經常使用Excel處理數據的coder翻閱) 【學習的細節是歡悅的歷程】 Python 官網:http…

基于 Spring AOP 實現安全檢查

在現代應用程序中,安全性是一個至關重要的方面。通過對系統中的關鍵操作進行安全檢查,可以有效防止未授權的訪問和操作。Spring AOP(面向切面編程)提供了一種優雅的方式來實現安全檢查,而無需修改業務邏輯代碼。本文將…

后端之路第三站(Mybatis)——入門配置

一、Mybatis是啥? 就是一個用java來操控數據庫的框架語言 之前學的datagrip或者navicat這些軟件里我們操作數據庫,原理是我們編寫完的操作語句發送到服務器傳送到數據庫系統,然后數據庫執行完之后再發送給服務器返回給datagrip或者navicat顯…

【linux/shell案例實戰】shell界面命令快捷鍵

快捷鍵及含義: Ctrl+u剪切光標之前的內容。Ctul+k剪切光標之后的內容。Ctrl+e讓光標移動到命令最前,Ctrl+a讓光標移動到命令最后Ctrl+y 粘貼剛才所刪除的內容。Ctrl+d 刪除光標所在…

GPT-5:AI的博士時代與我們的未來

目錄 引言第一部分:GPT-5技術突破預測1. NLP技術的革新1.1 算法進步對理解力提升的影響1.2 技術突破推動行業發展 2. 行業推動力2.1 教育行業的變革2.2 醫療行業的創新2.3 法律行業的效率提升 第二部分:智能系統與人類的協作1. 輔助決策的角色1.1 決策支…

游戲AI的創造思路-技術基礎-sigmoid函數詳解

在前面的機器學習和深度學習的內容中,大量出現了sigmoid函數,所以本篇為大家介紹下sigmoid函數,希望對大家理解前面的算法和后面的Transformer有所幫助 目錄 3.8. sigmoid函數 3.8.1. 定義 3.8.2. 性質 3.8.3. 應用 3.8.4. 缺點 3.8.5.…

Flutter實現頁面間傳參

帶參跳轉 步驟 在router中配置這個路由需要攜帶的參數,這里的參數是 arguments,注意要用花括號包裹參數名稱 在相應組件中實現帶參構造函數 在state類中可以直接使用${widget.arguments}來訪問到傳遞的參數 在其他頁面中使用Navigator.pushNamed()帶參跳轉

【昇思初學入門】第八天打卡-模型保存與加載

模型保存與加載 學習心得 保存 CheckPoint 格式文件,在模型訓練過程中,可以添加檢查點(CheckPoint)用于保存模型的參數,以便進行推理及再訓練使用。如果想繼續在不同硬件平臺上做推理,可通過網絡和CheckPoint格式文件生成對應的…

C++中常用的標志庫

標準庫 C標準庫是一個強大的工具集&#xff0c;它包含了一組豐富的類和函數&#xff0c;可以幫助開發者進行各種操作&#xff0c;如輸入輸出、字符串操作、數據結構管理、算法實現等。以下是一些常用的C標準庫及其使用方法。 1. 輸入輸出庫 <iostream> 用于標準輸入輸…

2024年最新通信安全員考試題庫

61.架設架空光纜&#xff0c;可使用吊板作業的情況是&#xff08;&#xff09;。 A.在2.2/7規格的電桿與墻壁之間的吊線上&#xff0c;吊線高度5m B.在2.2/7規格的墻壁與墻壁之間的吊線上&#xff0c;吊線高度6m C.在2.2/7規格的電桿與電桿之間的吊線上&#xff0c;吊線高度…

[leetcode]24-game

. - 力扣&#xff08;LeetCode&#xff09; class Solution { public:static constexpr int TARGET 24;static constexpr double EPSILON 1e-6;static constexpr int ADD 0, MULTIPLY 1, SUBTRACT 2, DIVIDE 3;bool judgePoint24(vector<int> &nums) {vector&l…

【C++LeetCode】【熱題100】三數之和【中等】-不同效率的題解【6】

題目&#xff1a; 暴力方法&#xff1a; class Solution { public:vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> res;std::unordered_set<std::string> uniqueValues;//保證結果唯一for(int i0;i<n…