我倒不是為了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;
#endifcircle.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);
#endifcircle.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 \n", 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);
#endifsquare.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 \n", 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 函數並不知道傳入的圖形列表分別都是哪些圖形,這些圖形又都怎麼計算面積和周長,它唯一知道的是,這些圖形計算面積和周長的接口是什麼,通過這個接口計算就好了