C 語言雖無原生類別,但可透過結構體包含函式指標模擬介面、繼承與多型。核心技巧:
project/ ├── Shape.h / Shape.c // 基底介面:Shape ├── Triangle.h / Triangle.c // 子類:三角形 ├── Rectangle.h / Rectangle.c // 子類:矩形 └── Main.c // 測試程式
#ifndef SHAPE_H_
#define SHAPE_H_
#include <stdlib.h>
// 前向宣告
typedef struct Shape Shape;
typedef Shape* p_shape;
// 虛函式表
typedef struct {
int (*getEdge)(p_shape);
double (*calcArea)(p_shape);
void (*_Shape)(p_shape); // 解構子
} ShapeVTable;
// Shape 結構體
struct Shape {
ShapeVTable *vptr; // 指向虛函式表
int edge;
};
// 介面函式宣告
p_shape Shape(int edge);
void _Shape(p_shape);
#endif
#include "Shape.h"
static int getEdge(p_shape this) { return this->edge; }
static double calcArea(p_shape this) { return 0.0; } // 純虛函式預設
static void _Shape(p_shape this) { free(this); }
static ShapeVTable vtable = {
.getEdge = getEdge,
.calcArea = calcArea,
._Shape = _Shape
};
p_shape Shape(int edge) {
p_shape s = (p_shape)malloc(sizeof(Shape));
if (s) {
s->vptr = &vtable;
s->edge = edge;
}
return s;
}
void _Shape(p_shape this) {
if (this) this->vptr->_Shape(this);
}
// Triangle.h
#ifndef TRIANGLE_H_
#define TRIANGLE_H_
#include "Shape.h"
typedef struct Triangle Triangle;
typedef Triangle* p_triangle;
struct Triangle {
Shape super; // 繼承:首欄位為基底
double bottom;
double height;
};
p_triangle Triangle(double bottom, double height);
void _Triangle(p_triangle);
#endif
// Triangle.c
#include "Triangle.h"
static int getEdge(p_shape this) {
p_triangle t = (p_triangle)this;
return 3;
}
static double calcArea(p_shape this) {
p_triangle t = (p_triangle)this;
return t->bottom * t->height / 2.0;
}
static void _Triangle(p_triangle this) {
if (this) this->super.vptr->_Shape((p_shape)this);
}
p_triangle Triangle(double bottom, double height) {
p_triangle t = (p_triangle)malloc(sizeof(Triangle));
if (t) {
t->super = *Shape(0); // 初始化基底部分
t->super.vptr->getEdge = getEdge;
t->super.vptr->calcArea = calcArea;
t->super.vptr->_Shape = (void(*)(p_shape))_Triangle;
t->bottom = bottom;
t->height = height;
}
return t;
}
// 結構體
struct Rectangle {
Shape super;
double width;
double height;
};
// 虛函式實現 getEdge 回傳 4,calcArea 回傳 width*height
#include <stdio.h>
#include "Triangle.h"
#include "Rectangle.h"
int main() {
p_triangle tri = Triangle(3.0, 4.0);
p_rectangle rect = Rectangle(5.0, 6.0);
p_shape shapes[2] = { (p_shape)tri, (p_shape)rect };
for (int i = 0; i < 2; ++i) {
printf("Shape %d: edges=%d, area=%.2f\n",
i+1,
shapes[i]->vptr->getEdge(shapes[i]),
shapes[i]->vptr->calcArea(shapes[i]));
shapes[i]->vptr->_Shape(shapes[i]); // 多型解構
}
return 0;
}
$ gcc -std=c99 Shape.c Triangle.c Rectangle.c Main.c -o oop_demo
$ ./oop_demo
Shape 1: edges=3, area=6.00
Shape 2: edges=4, area=30.00