I've studied and worked a lot on the subject for a month or two to get closer to the concept in a cleaner way, i.e. no virtual tables and no bunch of functions with prefixes etc. and most importantly functions are to be defined within structs as pointers to simulate OOP classes as much as possible.

Only constructors with prefixes are to be available publically. I also wanted to have the ability to call the override super method.

I'm not sure if following example is a compile time or run time polymorphism but it's satisfying the runtime aspects of it but then isn't it what we need without the need to have a look at the type of object? Please enlighten.

I'm putting it out there for critical analysis and review or problem with the approach.

The idea is to introduce a pointer of the parent type that retains a reference to original methods, the sub structures can override the parent implementation of the methods but the call to original methods are available via base pointer.

**main.c**

```
int main() {
    Person* person = Person_new("John", "Doe");
    Employee* employee = Employee_new("Jane", "Doe", "Acme", 40000);
    person->display(person); // displaying Person object
    puts("------");
    employee->super.display(&employee->super); // displaying employee info
    // ((Person *)employee)->display(employee); // or this
    person->release(person);
    employee->super.release(&employee->super);
    return 0;
}

```

**person.h**

```
typedef struct Person Person;
struct Person {
    Person *base; // to keep access to original funcs in case of overrides
    char* first;
    char* last;
    void (*display)(const Person *self);
    void (*release)(Person *self);
};
Person* Person_new(char* first, char* last);

```

**person.c**

```
static void display(const Person *self) {
    printf("First: %s\n", self->first);
    printf("Last: %s\n", self->last);
}

static void release(Person *self) {
    free(self);
}

Person* Person_new(char* first, char* last) {
    Person* self = malloc(sizeof *self);
    if(self == NULL) return NULL;

    self->first = strdup(first);
    self->last = strdup(last);
    self->display = display;
    self->release = release;

    self->base = self; // assigning reference to self to retain original functions in case they get overridden

    return self;
}

```

**employee.h**

```
typedef struct Employee Employee;
struct Employee {
    Person super;
    char* company;
    int salary;
};
Employee* Employee_new(char* first, char* last, char* company, int salary);

```

**employee.c**

```
static void display(const Person* self) {
    self->base->display(self->base); // calling super class func

    printf("Company: %s\n", ((Employee *)self)->company);
    printf("Salary: %d\n", ((Employee*)self)->salary);
}

static void release(Person *self) {
    self->base->release(self->base); // calling super class func
    free(self);
}

Employee* Employee_new(char* first, char* last, char* company, int salary) {
    Employee* employee = malloc(sizeof(Employee));
    if(employee == NULL) return NULL;

    employee->super = *Person_new(first, last);
    employee->super.display = display; // override
    employee->super.release = release; // override

    employee->company = strdup(company);
    employee->salary = salary;

    return employee;
}

```

> 
> 
> ```
> First: John
> Last: Doe
> ---
> First: Jane
> Last: Doe
> Company: Acme
> Salary: 40000
> 
> ```
> 
> 

**Edit**

Discussion with Pablo confirmed that the approach is correct. I'm still seeking some discussion on whether this approach falls under compile time or run time polymorphism.