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 \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);

#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 \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 函数并不知道传入的图形列表分别都是哪些图形,这些图形又都怎么计算面积和周长,它唯一知道的是,这些图形计算面积和周长的接口是什么,通过这个接口计算就好了

 

转载于:https://www.cnblogs.com/code-style/p/3218871.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值