首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

用 C 語言實現面向對象程式設計 (三):單一繼承與正方形類別特化

     編輯:關於C語言

繼承機制:extends 宏

/* oosm.h 片段 */
#define extends(type)   type type  /* 結構體首欄位嵌入父類型別 */

展開後:struct Child { Parent Parent; ... };
子類實例開頭即為父類實例 → 指標相容性:Child* 隱式轉換為 Parent*。

正方形類別:繼承矩形並特化

/* csqua.h */
#ifndef __CSQUA_H__
#define __CSQUA_H__
#include "crect.h"

class(csqua) {
    extends(crect);  // 單一繼承:嵌入 crect
};
#endif

記憶體佈局:

csqua 實例:
+------------------+
| crect (父類)     |  ← 偏移量 0
|   imeas          |     (介面繼承自 crect)
|   width          |
| height           |
+------------------+
| (csqua 無新增欄位) |
+------------------+

方法覆寫:csqua.c

#include "csqua.h"

static double peri(void* this) {
    crect* r = (crect*)this;  // 關鍵:this 實為 crect*
    return 4 * r->width;      // 正方形周長 = 4 * 邊長
}

static double area(void* this) {
    crect* r = (crect*)this;
    return r->width * r->width;  // 面積 = 邊長²
}

constructor(csqua) {
    /* 覆寫父類介面方法 */
    mapping(crect.imeas.peri, peri);
    mapping(crect.imeas.area, area);
}

destructor(csqua) {
    return 1;
}

關鍵點解析

關鍵點說明
this 型別建構子中 this 為 csqua*,但 extends 使其首欄位為 crect,轉型為 crect* 存取 width/height
介面繼承csqua 自動擁有 imeas (來自 crect),無需重複 implements
方法覆寫mapping(crect.imeas.peri, peri) 直接覆蓋父類建構子中綁定的函數指標
建構順序OOSM 僅呼叫 csqua_constructor,不自動呼叫父類建構子 → 子類建構子需完全負責初始化(含介面綁定)

完整多態測試:圓形、矩形、正方形

#include 
#include "imeas.h"
#include "ccirc.h"
#include "crect.h"
#include "csqua.h"

int main() {
    ccirc* c = ccirc_new();
    crect* r = crect_new();
    csqua* s = csqua_new();
    
    c->radius = 9.23;
    r->width = 23.09; r->height = 78.54;
    s->crect.width = 200.00;  // 存取繼承欄位:s->crect.width
    
    printf("Circle:    直徑=%.2f 周長=%.2f 面積=%.2f\n", 
           c->diam(c), c->imeas.peri(c), c->imeas.area(c));
    printf("Rectangle: 周長=%.2f 面積=%.2f\n", 
           r->imeas.peri(r), r->imeas.area(r));
    printf("Square:    周長=%.2f 面積=%.2f\n", 
           s->crect.imeas.peri(s), s->crect.imeas.area(s));
    
    ccirc_delete(c);
    crect_delete(r);
    csqua_delete(s);
    return 0;
}

輸出結果

Circle:    直徑=18.46 周長=57.99 面積=267.35
Rectangle: 周長=203.26 面積=1813.73
Square:    周長=800.00 面積=40000.00

OOSM 完整系列總結

篇章核心內容關鍵宏
(一) 核心架構宏包定義、類別/介面/建構/解構/映射class interface constructor destructor mapping
(二) 介面多態imeas 介面、crect/ccirc 實作、void* 多態implements interface
(三) 單一繼承extends(crect)、csqua 覆寫、記憶體佈局extends

C 語言 OOP 的本質與權衡

  • 本質:結構體嵌套 + 函數指標 + 手動 this 傳遞 + 宏語法糖
  • 優勢:零開銷、完全可控、可移植至任何 C 編譯器、教學價值極高
  • 代價:
    • 無存取控制 (private/protected)
    • 手動 this 傳遞冗長 (c->imeas.peri(c))
    • 單一繼承、無虛解構子鏈、無 RTTI
    • 建構子不自動鏈式呼叫父類
  • 適用場景:嵌入式、核心模組、教學、極簡庫開發

擴展方向(若需)

  1. 多重介面:結構體嵌套多個介面,implements 遞增偏移量
  2. 建構子鏈:宏生成 parent_constructor(this) 呼叫
  3. 虛解構子:介面添加 destroy,解構子鏈式調用
  4. 屬性存取器:宏生成 get_width/set_width 封裝欄位

面向對象是思想,非語言專利。C 語言以最樸素方式揭示了封裝、繼承、多態的機械本質——這正是理解任何 OO 語言底層運作的鑰匙。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved