C语言实现的OOP
我倒不是为了OOP而OOP,实在是OOP的一些特征,例如封装,多态其实是软件工程思想,这些思想不分语言,遵循了这些思想可以使得程序更有弹性,更易修改和维护,避免僵化,脆弱
shape.h 该文件定义的是图形接口,所有具体图形都必须实现自己计算面积,周长等API
#ifndef SHAPE_H #define SHAPE_H typedef struct shape_t { void *shapeData; void (*area)(void *); void (*release)(void *); }Shape; #endif
circle.h 圆形接口
#ifndef CIRCLE_H #define CIRCLE_H typedef struct { double r; }CircleData; typedef struct { void *shapeData; void (*area)(void *); void (*release)(void *); }Circle; Circle *makeCircle(double r); #endif
circle.c 圆形的实现代码,static修饰的函数其实相当于private函数
#include <assert.h> #include <stdlib.h> #include <stdio.h> #include "circle.h" const double PI = 3.14159; static void area(void *shape) { Circle *_circle = (Circle *)shape; CircleData* data = (CircleData*)_circle->shapeData; printf("the circle area is %f ", data->r * data->r * PI); } static void release(void *shape) { Circle *_circle = (Circle *)shape; CircleData* data = (CircleData*)_circle->shapeData; free(data); free(_circle); } Circle *makeCircle(double r) { CircleData* circleData = (CircleData*)malloc(sizeof(CircleData)); Circle* circle = (Circle*)malloc(sizeof(Circle)); assert(circleData != NULL); assert(circle != NULL); assert(r > 0); circleData->r = r; circle->shapeData = circleData; circle->area = &area; circle->release = &release; return circle; }
square.h
#ifndef SQUARE_H #define SQUARE_H typedef struct { double x; double y; }SquareData; typedef struct { void *shapeData; void (*area)(void *); void (*release)(void *); }Square; Square *makeSquare(double x, double y); #endif
square.c
#include <assert.h> #include <stdlib.h> #include <stdio.h> #include "square.h" static void area(void *shape) { Square *square = (Square *)shape; SquareData* data = (SquareData*)square->shapeData; printf("the square area is %f ", data->x * data->y); } static void release(void *shape) { Square *square = (Square *)shape; SquareData* data = (SquareData*)square->shapeData; free(data); free(square); } Square *makeSquare(double x, double y) { SquareData* squareData = (SquareData*)malloc(sizeof(SquareData)); Square* square = (Square*)malloc(sizeof(Square)); assert(squareData != NULL); assert(square != NULL); assert(x > 0 && y > 0); squareData->x = x; squareData->y = y; square->shapeData = squareData; square->area = &area; square->release = &release; return square; }
main.c 所有的工作,都为了它,是为了让它的代码稳定
#include <stdio.h> #include "shape.h" #include "circle.h" #include "square.h" void printShapeArea(Shape **shape,int length) { int i=0; for(i=0;i<length;i++) { shape[i]->area(shape[i]); shape[i]->release(shape[i]); } } int main() { Shape *p[3] = {(Shape*)makeCircle(3.2),(Shape*)makeCircle(3.2),(Shape*)makeSquare(3.1,4)}; printShapeArea(p,3); return 0; }
总结:
printShapeArea 函数并不知道传入的图形列表分别都是哪些图形,这些图形又都怎么计算面积和周长,它唯一知道的是,这些图形计算面积和周长的接口是什么,通过这个接口计算就好了
分类: 架构设计