三.多态(C面向对象开发)

内容参考于《抽象接口技术和组件开发规范及其思想》

三.多态

所谓多态,其字面含义就是具有“多种形式”。从调用者的角度看对象,会发现它们非常相似,难以区分,但是这些被调用对象的内部处理实际上却各不相同。 换句话说,各个对象虽然内部处理不同,但对于使用者(调用者)来讲,们却是相同的。

1. 示例1:(不是最终解)

一个学生类,自我介绍的不同,可以表现为多态。
student.h

#ifndef __STUDENT_H
#define __STUDENT_H

struct student {
	int(*student_self_introduction) (struct student *p_student);
	char name[10]; /* 姓名 (假定最长 10 字符) */
	unsigned int id; /* 学号 */
	char sex; /* 性别:'M',男; 'F' ,女 */
	float height; /* 身高 */
	float weight; /* 体重 */

};

int student_init(struct student *p_student,
	char *p_name,
	unsigned int id,
	char sex,
	float height,
	float weight,
	int(*student_self_introduction) (struct student *));
/* 学生类提供的自我介绍方法 */
static inline
int student_self_introduction(struct student *p_student)
{
	return p_student->student_self_introduction(p_student);
}

#endif

student.c

#include "student.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
int student_init(struct student *p_student,
	char *p_name,
	unsigned int id,
	char sex,
	float height,
	float weight,
	int(*student_self_introduction) (struct student *));
{
	memcpy(p_student->name, p_name, strlen(p_name));

	p_student->id = id;
	p_student->sex = sex;
	p_student->height = height;
	p_student->weight = weight;
	p_student->student_self_introduction = student_self_introduction;	

	return 0;
}

main.c

static int student_zhangsan_introduction(struct student *p_student)
{
	const char *str = "亲爱的老师,同学们,我叫张三,来自美丽的四川,今年 18 岁, "
		"是一个自信,开朗,友好,积极向上的人,我有着广泛的兴趣爱"
		"好,喜欢健身、打篮球、看书、下棋、听音乐,特别对主持和街"
		"舞有着浓厚的兴趣,希望能和同学们做好朋友,一起学习,一起"
		"玩耍……";
	printf("%s\n", str);
	return 0;
}
static void first_class(struct student *p_students, int num)
{
	int i;
	for (i = 0; i < num; i++) {
		student_self_introduction(&p_students[i]);

	}
}

int main()
{
	struct student student[50];

	/* 根据每个学生的信息,依次创建各个学生对象 */
	student_init(&student[0], "zhangsan", 2010447222, 'M', 173, 60, student_zhangsan_introduction);
	// ...

	/* 上第一节课 */
	first_class(student, 50);
}
  1. 多态的核心是:对于上层调用者,不同的对象可以使用完全相同的操作方法,但是每个对象可以有各自不同的实现方式。
  2. 虽然函数指针同属性一样,放在结构体类型的定义中,但函数指针不能视为普通的属性,其应视为一种方法(是被用来调用的),在面向对象编程中,通常将类中的函数指针称之为抽象方法(因其在定义类时没有实现, 所以是“抽象” 的)。此外,往往还会将函数指针封装到抽象类(最终解)中。
2. 示例2:

标准输出输出的框架
file.h

 struct FILE {
	void(*open) (char *name, int mode);
	void(*close) ();
	int(*read) ();
	void(*write) ();
	void(*seek) (long index, int mode);
};

console.c

#include "file.h"

static void open(char *name, int mode)
{
	// 实现代码
}

static void close()
{
	// 实现代码
}

static int read()
{
	// 实现代码
}

static void write()
{
	// 实现代码
}

static void seek(long index, int mode)
{
	// 实现代码
}

struct FILE console = { open, close, read, write, seek };

main.c

exttern struct FILE console;
struct FILE * STDOUT = &console;
// 对于printf
void putchar (char c)
{
	STDOUT->write(&c, 1);
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值