【QT/C++】實例理解類間的六大關系之泛化關系(Generalization)

【QT/C++】實例理解類間的六大關系之泛化關系(Generalization)

在前面章節一文完美概括UML類圖及其符號(超詳細介紹)中已經對泛化關系的概念進行了總結,本文我將用實際案例來進一步理解泛化關系,以便應對未來的考試或面試!

(關注不迷路哈!!!)


文章目錄

  • 【QT/C++】實例理解類間的六大關系之泛化關系(Generalization)
    • 前言 📊
    • 一、核心概念 🔍
    • 二、繼承類型對比表 🔒
    • 三、代碼示例與多態實現 ??
      • 1. 代碼實現邏輯
      • 2. 完整代碼展示
      • 3. 代碼實現框架
      • 4. 代碼交互流程
    • 四、泛化關系的優缺點與最佳實踐 💎
    • 五、面試常見問題及回答 🚀
      • 1. 問:何時使用繼承?何時用組合??
      • 2. 問:為什么父類需要虛析構函數(virtual)??
      • 3. 問:多重繼承會導致什么問題,如何解決??
      • 4. 問:如何設計圖形系統且支持多態繪制??
    • 總結 🛠?


前言 📊

泛化關系

// 基類(抽象) // 數據庫Database
class Database {
public:virtual void connect() = 0;  // 純虛函數 // 連接數據庫
};// 派生類(實現)// MySQL是數據庫Database
class MySQL : public Database {
public:void connect() override {cout << "Connecting to MySQL..." << endl;}
};// 派生類(實現)// PostgreSQL是數據庫Database
class PostgreSQL: public Database {
public:void connect() override {cout << "Connecting to PostgreSQL..." << endl;}
};

一、核心概念 🔍

父類定義通用接口,子類實現具體行為

特性說明
本質繼承機制(父子類之間的"is-a"關系)
設計原則子類繼承父類屬性和方法,并可擴展新功能
多態基礎父類指針/引用可指向子類對象,實現運行時綁定
UML類圖表示子類 ————? 父類(實線 + 空心三角箭頭)
代碼關鍵字C++ 代碼: class Sub : public Base

二、繼承類型對比表 🔒

繼承方式基類成員訪問權限變化適用場景耦合度
public基類public→子類public,基類protected→子類protected嚴格"is-a"關系(如Dog is Animal
protected基類public/protected→子類protected限制外部訪問,保留內部復用
private基類public/protected→子類private“以…方式實現”(非"is-a")

📝 關鍵規則:基類private成員在子類中始終不可見(存在但無法訪問)。


三、代碼示例與多態實現 ??

1. 代碼實現邏輯

代碼實現邏輯

2. 完整代碼展示

#include <iostream>
using namespace std;// 基類(抽象接口)
class Database {
public:virtual void connect() = 0;  // 純虛函數,父類定義 virtual 接口方法virtual ~Database() = default; // ? 虛析構函數(避免資源泄漏),基類析構函數必須為 virtual,否則子類資源泄漏
};// 子類實現
class MySQL : public Database {  // public繼承
public:void connect() override { // 子類用 override 顯式重寫(C++11及以上)cout << "MySQL: 連接成功" << endl;}
};class PostgreSQL : public Database {
public:void connect() override { // 子類用 override 顯式重寫(C++11及以上)cout << "PostgreSQL: 連接成功" << endl;}
};// 多態調用
void connectDatabase(Database* db) {db->connect();  // 運行時綁定具體實現
}int main() {Database* db1 = new MySQL(); // 父類指針指向子類對象connectDatabase(db1);  // 輸出: MySQL: 連接成功Database* db2 = new PostgreSQL(); // 父類指針指向子類對象connectDatabase(db2);  // 輸出: PostgreSQL: 連接成功delete db1;delete db2;return 0;
}

3. 代碼實現框架

代碼實現框架

4. 代碼交互流程

代碼交互流程


四、泛化關系的優缺點與最佳實踐 💎

維度優點缺點最佳實踐
代碼復用減少冗余代碼,子類復用父類邏輯父類變更可能破壞子類功能(高耦合)優先用組合(has-a)替代繼承
多態支持運行時動態綁定,擴展性強虛函數調用有性能開銷基類析構函數必須為virtual
設計易于表達層次關系(如動物→貓/狗)多重繼承導致菱形問題(需虛繼承解決)避免超過3層繼承深度

泛化關系在設計上應遵循里氏替換原則:子類必須完全兼容父類行為,父類出現處可替換為子類。

💡 組合優先示例

class Engine {};   // 引擎類
class Car {
private:Engine engine; // 組合而非繼承(Car has an Engine)
};// 而非:
class Car : public Engine {};  // 錯誤繼承

五、面試常見問題及回答 🚀

1. 問:何時使用繼承?何時用組合??

  • 繼承
    1. 當需要表達嚴格的"is-a"關系時(如Circle is a Shape
    2. 需要實現運行多態時
    3. 符合里氏替換原則的場景

  • 組合:當需要"has-a"關系或避免耦合時(如Car包含Engine

2. 問:為什么父類需要虛析構函數(virtual)??

  • 避免內存泄漏
    Base* p = new Derived();// 若基類析構非虛,僅調用Base::~Base() → 內存泄漏
    delete p; // 若~Base()非虛,僅調用~Base()導致Derived部分泄漏
    

3. 問:多重繼承會導致什么問題,如何解決??

    1. 菱形繼承問題(需虛繼承解決)
      class A {};
      class B : virtual public A {};
      class C : virtual public A {};
      class D : public B, public C {};
      
    1. 增加復雜度,易引發命名沖突
    1. 推薦用接口繼承+組合替代

4. 問:如何設計圖形系統且支持多態繪制??

  • 具體實現代碼示例
    class Shape {
    public:virtual double area() const = 0;virtual void draw() const = 0;virtual ~Shape() = default;
    };class Circle : public Shape {double radius;
    public:double area() const override { return 3.14 * radius * radius; }void draw() const override {cout << "○" << endl;}
    };
    

設計圖形系統


總結 🛠?

  • 繼承的優缺點
    優點是可以實現代碼重用和多態;
    缺點是可能增加類之間的耦合(降低通用性),過度使用繼承可能導致層次過深、結構復雜。
  • 組合優先于繼承
    在可能的情況下,優先使用組合而不是繼承,因為組合的耦合度較低。

通過合理使用泛化關系,可構建高擴展性的面向對象系統,但需警惕過度繼承導致的維護復雜性。

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

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

相關文章

【微服務的數據一致性分發問題】究極解決方案

文章目錄一、微服務數據分發1、簡介2、典型場景&#xff08;1&#xff09;跨服務業務流程協同&#xff08;2&#xff09;數據副本同步&#xff08;讀寫分離&#xff09;&#xff08;3&#xff09;實時狀態通知&#xff08;4&#xff09;數據聚合與統計分析&#xff08;5&#x…

挖幣與區塊鏈技術有怎樣的聯系?

挖幣&#xff08;通常指加密貨幣挖礦&#xff09;與區塊鏈技術有著緊密的聯系&#xff0c;挖礦是區塊鏈網絡維持運行和安全的重要機制之一&#xff0c;具體聯系如下&#xff1a;1. 挖礦是區塊鏈共識機制的核心環節區塊鏈通過“共識機制”確保全網節點對交易記錄達成一致&#x…

C數據結構:二叉樹(下)

C數據結構&#xff1a;二叉樹&#xff08;下&#xff09; 1.二叉樹遞歸結構遍歷 2.例題 3.二叉樹的性質 1.二叉樹遞歸結構遍歷 我們先創建一個如下圖所示的二叉樹。typedef int BTDataType; typedef struct BinaryTreeNode {BTDataType data;struct BinaryTreeNode* left;struc…

Linux系統的網絡管理(一)

一、網絡參數配置&#xff1a;搭建穩定網絡基礎網絡參數配置是 Linux 網絡管理的起點&#xff0c;根據操作方式可分為圖形化配置、命令行配置和配置文件配置&#xff0c;不同方式適用于不同場景&#xff08;臨時調試 / 永久生效&#xff09;。1. 圖形化配置&#xff1a;依賴 Ne…

Web程序設計

一、控件基礎 文本框、按鈕事件的使用 <% Page Language"C#" AutoEventWireup"true" CodeFile"User_Login.aspx.cs" Inherits"User_Login" %><!DOCTYPE html><html xmlns"http://www.w3.org/1999/xhtml"&g…

復合設計模式

復合設計模式復合設計模式是一種結構模式&#xff0c;可讓您統一處理單個對象和對象的組合。它允許您構建樹狀結構&#xff08;例如&#xff0c;文件系統、UI 層次結構、組織結構&#xff09;&#xff0c;客戶端可以使用同一界面處理單個元素和元素組。它在以下情況下特別有用&…

使用 Prometheus 監控服務器節點:Node Exporter 詳解與配置

前言 在上一篇文章中&#xff0c;我們介紹了如何在 CentOS 上部署 Prometheus 并使用 systemd 進行管理。本文將繼續深入&#xff0c;講解如何使用 Prometheus 監控服務器節點&#xff0c;重點介紹 Node Exporter 的作用、安裝和配置方法。 Node Exporter 是 Prometheus 生態…

C# 編寫一個XmlToDota的轉換工具

以下代碼可以將Labelme標注的旋轉框Xml格式文件轉換為Yolo標注格式的txt文件&#xff0c;以便用Yolo OBB訓練自己的數據集&#xff1a;using System; using System.Collections.Generic; using System.IO; using System.Xml; using System.Linq; using System.Globalization;na…

[Android] 人體細胞模擬器1.5

[Android] 人體細胞模擬器1.5 鏈接&#xff1a;https://pan.xunlei.com/s/VOYVUieTpjNVJq-bMys4EEDGA1?pwdm7m6# 省流:這個軟件的開發者有點逆天&#xff0c;一個模擬人體器官的軟件&#xff0c;細致到有血液報告&#xff0c;還縫合了生理學和病理學&#xff0c;甚至還能做切…

【Linux基礎知識系列】第一百一十篇 - 使用Nmap進行網絡安全掃描

在網絡安全管理中&#xff0c;了解網絡中的設備、開放的端口以及運行的服務是至關重要的。Nmap&#xff08;Network Mapper&#xff09;是一個功能強大的開源工具&#xff0c;用于網絡發現和安全審計。它可以掃描網絡中的設備&#xff0c;識別開放的端口和運行的服務&#xff0…

【Linux倉庫】進程的“奪舍”與“飛升”:exec 驅動的應用現代化部署流水線

&#x1f31f; 各位看官好&#xff0c;我是egoist2023&#xff01; &#x1f30d; Linux Linux is not Unix &#xff01; &#x1f680; 今天來學習exec系列的進程程序替換,從"fork"的"克隆"到"exec"的"重生"。 &#x1f44d; 如果覺…

Reachability Query

題目分析 該代碼實現了一個動態集合管理系統&#xff0c;支持三種操作&#xff1a;合并集合、切換元素狀態、查詢集合中是否- 存在活躍元素。核心數據結構為并查集&#xff0c;結合狀態標記數組和計數器。關鍵數據結構與函數 初始化 fa[N]&#xff1a;并查集父節點數組&#xf…

SSL移動接入方案和移動資源發布

一、SSL VPN概述SSL VPN是一種基于SSL/TLS協議的遠程安全接入技術&#xff0c;因其廣泛兼容Web瀏覽器&#xff0c;支持“無客戶端”部署&#xff0c;具備易于使用和維護的特點。它通過插件系統支持非Web類TCP/UDP應用&#xff0c;并且支持對用戶的訪問可以做出限制&#xff0c;…

C++STL---count() 統計容器中特定元素出現次數

在 C 標準庫中&#xff0c;count 是一個用于統計容器中特定元素出現次數的函數&#xff0c;定義在 <algorithm> 頭文件中。它可以快速計算某個值在容器&#xff08;如數組、vector、list 等&#xff09;中出現的次數&#xff0c;避免手動編寫循環計數的麻煩。 一、函數原…

Tesla自動駕駛域控制器(AutoPilot HW)的系統化梳理

目前網絡上對Tesla自動駕駛硬件&#xff08;AP1-AP4、HW1.0-HW4.0&#xff09;迭代的相關介紹比較混亂&#xff0c;本文這里進行系統化梳理并澄清&#xff0c;并對一些錯誤進行更正。1、AutoPilot HW迭代圖圖1 AutoPilot HWMCU迭代圖圖2 AutoPilot HW 散熱設計迭代圖&#xff0…

C 語言:第 20 天筆記:typedef(類型重命名規則、應用場景與實戰案例)

C語言&#xff1a;第20天筆記 內容提要 構造類型枚舉類型typedef綜合案例:斗地主預處理 構造類型&#xff1a;枚舉類型 使用建議 如果定義不相干的常量&#xff0c;使用宏定義&#xff08;符號常量&#xff09;&#xff1b;如果需要定義一組相關聯的常量&#xff08;如月份011、…

在 vue3 和 vue2 中,v-for 和 v-if 可以一起用嗎,區別是什么

在 Vue 2 和 Vue 3 中&#xff0c;v-for 和 v-if 可以一起使用&#xff0c;但兩者在處理順序和推薦用法上存在明顯區別&#xff0c;主要體現在優先級和最佳實踐上&#xff1a; 1. Vue 2 中的 v-for 與 v-if優先級&#xff1a;v-for 的優先級高于 v-if。 這意味著 Vue 會先循環渲…

Linux-進程相關函數

文章目錄Linux-進程相關函數父子進程關系父子進程地址空間getpid函數 獲取本進程號getppid函數 獲取當前進程的進程的父進程號getpgid函數 獲取進程組號示例fork函數 創建進程區分父子進程exit函數 進程退出wait函數 等待子進程退出waitpid函數Linux-進程相關函數 每個進程都由…

數據挖掘 6.1 其他降維方法(不是很重要)

6.1 Other dimensionality reduction methods 6.1 其他降維方法 其他降維方法前言問題答案流形3 降維大綱3.1 線性方法3.2 非線性方法3.2.1 流形學習方法&#xff08;Manifold Learning&#xff09;3.2.2 概率方法&#xff08;Probabilistic Approaches&#xff09;3.2.3 拓撲數…

Unity中的特殊文件夾

一.工程路徑獲取print(Application.dataPath);只用于游戲開發編輯器模式下&#xff0c;游戲發布后此路徑就不存在了二.Resources 資源文件夾//路徑獲取: //一般不獲取 //只能使用Resources相關API進行加載 //如果硬要獲取 可以用工程路徑拼接print(Application.dataPath "…