C 语言面向对象-- 多态

在面相对象的设计过程中,很重要的一个特性就是实现运行时多态。在我们的前面一篇文章中我们讨论过了如何实现继承。那么这篇文章中我们就将着上一次的例子,来说说在C语言中如何利用语言的灵活性来实现多态。

C 语言面向对象– 继承
C 语言面向对象– 多态

在继承的例子里,我们实现了一个基类 Person

typedef struct _person{
    char name[128];
    int age;
    void (*setName)(struct _person * person, char* name);
    void (*setAge)(struct _person * pseron,int age);
    char *(*getName)(struct _person * person,int *len);
    int (*getAge)(struct _person * pseron);
}Person;


static void setName(struct _person * person, char* name){
    if(person == NULL)
        return;
    memcpy(person->name, name, strlen(name));
    return;
}

static void setAge(struct _person * person,int age){
    if(person == NULL)
        return;
    person->age = age;
    return;
}
static char * getName(struct _person * person, int *len){
    if(person == NULL)
        return NULL;
    *len = (int)strlen(person->name);
    return person->name;
}
static int getAge(struct _person * person){
    if(person == NULL)
        return -1;
    return person->age;
}

Person * Person_new(char * name, int age){
    Person * person = NULL;
    person = (Person *)malloc(sizeof(Person));
    memset(person, 0, sizeof(Person));

    person->getAge = getAge;
    person->getName = getName;
    person->setName = setName;
    person->setAge = setAge;

    memcpy(person->name, name, strlen(name));
    person->age = age;
    return person;
}

void Person_delete(Person * person){
    if(person == NULL)
        return;
    free(person);
    return;
}

一个派生类Student

typedef struct _student{

    Person *person;
    char school[128];
    void (*setSchool)(struct _student * student, char *school);
    char * (*getSchool)(struct _student * student, int *len);
    void (*setName)(struct _student * student, char* name);
    void (*setAge)(struct _student * student,int age);
    char *(*getName)(struct _student * student,int *len);
    int (*getAge)(struct _student * student);


}Student;




static void stu_setSchool(struct _student * student, char *school){
    if(student == NULL)
        return;
    memcpy(student->school, school, strlen(school));
    return;

}
static char * stu_getSchool(struct _student * student, int *len){
    if(student == NULL)
        return NULL;
    *len = (int)strlen(student->school);
    return student->school;
}


static void stu_setName(struct _student * student, char* name){
    if(student == NULL)
        return;
    student->person->setName(student->person,name);
    return;
}

static void stu_setAge(struct _student * student,int age){
    if(student == NULL)
        return;
    student->person->setAge(student->person,age);
    return;
}
static char * stu_getName(struct _student * student, int *len){
    if(student == NULL)
        return NULL;

    return student->person->getName(student->person, len);
}
static int stu_getAge(struct _student * student){
    if(student == NULL)
        return -1;
    return student->person->getAge(student->person);
}

Student *Student_new(char * name, int age){
    Student * student = NULL;
    student = (Student *) malloc(sizeof(Student));
    memset(student, 0, sizeof(Student));
    student->person = Person_new(name, age);
    student->getSchool = stu_getSchool;
    student->setSchool = stu_setSchool;
    student->getAge =stu_getAge;
    student->getName = stu_getName;
    student->setName = stu_setName;
    student->setAge = stu_setAge;

    return student;
}

void Student_delete(Student * student){
    if(student == NULL)
        return;
    Person_delete(student->person);
    free((void *)student);
    return;
}

这次我们在实现一个Employee 类,并且同样继承自Person

typedef struct _employee{

    Person *person;
    char job[128];
    void (*setJob)(struct _employee * employee, char *job);
    char * (*getJob)(struct _employee * employee, int *len);
    void (*setName)(struct _employee * employee, char* name);
    void (*setAge)(struct _employee * employee,int age);
    char *(*getName)(struct _employee * employee,int *len);
    int (*getAge)(struct _employee * employee);


}Employee;




static void emp_setJob(struct _employee * employee, char *job){
    if(employee == NULL)
        return;
    memcpy(employee->job, job, strlen(job));
    return;

}
static char * emp_getJob(struct _employee * employee, int *len){
    if(employee == NULL)
        return NULL;
    *len = (int)strlen(employee->job);
    return employee->job;
}


static void emp_setName(struct _employee * employee, char* name){
    if(employee == NULL)
        return;
    employee->person->setName(employee->person,name);
    return;
}

static void emp_setAge(struct _employee * employee,int age){
    if(employee == NULL)
        return;
    employee->person->setAge(employee->person,age);
    return;
}
static char * emp_getName(struct _employee * employee, int *len){
    if(employee == NULL)
        return NULL;

    return employee->person->getName(employee->person, len);
}
static int emp_getAge(struct _employee * employee){
    if(employee == NULL)
        return -1;
    return employee->person->getAge(employee->person);
}

Employee *Employee_new(char * name, int age){
    Employee * employee = NULL;
    employee = (Employee *) malloc(sizeof(Employee));
    memset(employee, 0, sizeof(Employee));
    employee->person = Person_new(name, age);
    employee->getJob = emp_getJob;
    employee->setJob = emp_setJob;
    employee->getAge =emp_getAge;
    employee->getName = emp_getName;
    employee->setName = emp_setName;
    employee->setAge = emp_setAge;

    return employee;
}

void Employee_delete(Employee * employee){
    if(employee == NULL)
        return;
    Person_delete(employee->person);
    free((void *)employee);
    return;
}

然后我们定义一个函数,叫做PrintInfo 用来输出Person类以及其子类的相关信息。定义如下

void PrintInfo(void * _person){
    if(_person != NULL)
    {
        int len;
        Person **person = (Person **)_person;
        printf("my information: name %s, age %d\n", (*person)->getName(*person,&len), (*person)->getAge(*person));
        return;
    }
    printf("person is NULL\n");
}

我们的主调用程序如下:

int main(int argc, const char * argv[]) {
    int len;
    Student *student = Student_new("tom", 15);
    printf("Hello, my name is %s, %d years old \n", student->getName(student, &len),student->getAge(student));



    Employee * employee = Employee_new("jerry", 28);
    printf("Hello, my name is %s, %d years old \n", employee->getName(employee, &len), employee->getAge(employee));


    PrintInfo((void *)student);
    PrintInfo((void *)employee);

    Student_delete(student);
    student = NULL;

    Employee_delete(employee);
    employee = NULL;
    return 0;
}

运行之后,我们可以看到输出结果如下:

Hello, my name is tom, 15 years old 
Hello, my name is jerry, 28 years old 
my information: name tom, age 15
my information: name jerry, age 28

我们这个程序的多态性就体现在的PrintInfo 这个函数里。这样,如果我们设计一个系统,我们也可以做到像用C++ 或用 Java语言一样,针对接口编程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值