Encapsulation, inheritance and polymorphism in C

On 2018/06/27 at 22:31

Encapsulation

  1. Encapsulate the data and functions in the object
  2. Hide the implementation and data from the users

nas.h

struct Nas; // forward declaration
struct Nas* newNas(int bays, double price);
double pricePerBay(struct Nas *nas);

nas.c

struct Nas {
    int bays;
    double price;
};
struct Nas* makeNas(int bays, double price) {
    struct Nas *nas = (struct Nas*)malloc(sizeof(struct Nas));
    nas->bays = bays;
    nas->price = price;
    return nas;
}
double pricePerBay(struct Nas *nas)
{
    return nas->price / nas->bays;
}

Users can not access of the member of Nas but only its functions because of the power of forward declaration. (Users can only use the pointer of Nas)

Inheritance

Put the parent class as first member.

10g_nas.h

struct TenGNas; // forward declaration
struct TenGNas* newTenGNas(bool isSFP, int bays, double price);
bool isSFP(struct TenGNas *nas);

10g_nas.c

struct TenGNas {
    struct Nas base;
    bool isSFP;
};
struct TenGNas* makeTenGNas(bool isSFP, int bays, double price) {
    struct TenGNas *nas = (struct TenGNas*)malloc(sizeof(struct TenGNas));
    nas->isSFP = isSFP;
    nas->base.bays = bays;
    nas->base.price = price;
    return nas;
}
bool isSFP(struct TenGNas *nas)
{
    return nas->isSFP;
}

client.c

int main()
{
    struct TenGNas *nas = makeTenGNas(true, 4, 100);
    printf ("SPF: %s\n", isSFP(nas) ? "yes" : "no");
    printf ("price per bay: %lf\n", pricePerBay((struct Nas*)nas));

    return 0;
}

(struct Nas*)nas up-casting will be done by OO-language automatically, however, in C we have to do it manually.

Polymorphism

Polymorphism can be done by using function pointers point to different functions for different sub-class.

nas.h

struct Nas;
struct DS918;
struct DS218;

struct DS918* makeDS918();
struct DS218* makeDS218();

void printModelName(struct *Nas nas);

nas.c

void printModelNameDS918()
{
    puts("DS918");
}
void printModelNameDS218()
{
    puts("DS218");
}
struct Nas {
    void (*printModelName)();
};
struct DS918 {
    struct Nas base;
};
struct DS218 {
    struct Nas base;
};
struct DS918* makeDS918()
{
    struct DS918 *nas = (struct DS918*)malloc(sizeof(DS918));
    nas->base.printModelName = printModelNameDS918;

    return nas;
}
struct DS218* makeDS218()
{
    struct DS218 *nas = (struct DS218*)malloc(sizeof(DS218));
    nas->base.printModelName = printModelNameDS218;

    return nas;
}
void printModelName(struct Nas *nas)
{
    nas->printModelName();
}

client.c

int main()
{
    struct DS918 *ds918 = makeDS918();
    printModelName((struct Nas*)ds918);

    struct DS218 *ds218 = makeDS218();
    printModelName((struct Nas*)ds218);
}

Now printModelName is a polymorphism function.

Comments