C面向对象与多态性

一、多态性

面向对象的基本思考方式是将数据和处理数据的行为放到一起,降低耦合性。其要点就是不要将数据和处理数据的行为分开

在 http://blog.csdn.net/kangguang/article/details/79229064中“带有检查功能的栈”的示例代码就将上限数据,下限数据和栈自身的数据都放在了栈结构体中,结果增加了耦合性。也就是说,仅将数据整合在一起,是绝对无法降低耦合性的。

面向对象编程有许多特性,其中非常重要的一个特性就是多态性。所谓多态性就是指从调用者的角度看对象,会发现它们非常相似,难以区分,但是这些被调用对象的内部处理实际上各不相同。在上篇的例子中,在校验push函数的值时,调用者只会调用Validator的 Validator函数,从外部并不知道其中到底进行了怎样的校验处理。


bool validate(Validator * p,int val)
{
    if (!p)
    {
        return true;
    }
    return p->validator(p,val);
}
实际上内部到底进行了怎样的校验处理,取决于Validator自身。像这样,通过将数据和处理成对分离,并使用结构体和函数指针实现多态性,被分离出来的部分也可以作为组件被重复利用。

二、继承


typedef struct Validator{
    bool (* const validator)( struct Validator * pThis,int val);//1
    void * const pData;//2
   
}Validator;
   这个方法适用于简单情况,但情况稍微复杂一些,就显得麻烦了。范围检查校验器中,这个pData指向的是Range结构体。假设现在需要扩展检查校验器的功能,使得栈中只能接受奇数或者偶数,那么仅简单地扩展Range的话,程序中的角色就会变得很模糊。虽然C不是面向对象语言,无法使用继承功能优雅地解决这个问题,但还是有稍好一点的办法的。

 重新对代码进行编写:


//1
typedef struct Validator{
    bool (* const validator)( struct Validator * pThis,int val);
}Validator;
    
//2
typedef struct{
    //2-1
    Validator base;
    const int min;
    const int max;
}RangeValidator;

//3
typedef struct{
    Validator base;//3-1
    int previousValue;

}PreviousValueValidator;

#define newRangeValidator(min,max){            \
    {validateRange},                           \
    (min),(max)                                \
}
 
#define newPreviousValidator(){                \
    {validatePrevious},                        \
    0                                          \
}

bool validateRange(Validator * pThis,int val)
{
    RangeValidator * pRange = (RangeValidator *)pThis;
    return pRange->min<=val && val<= pRange->max;
}
bool validatePrevious(Validator * pThis,int val)
{
    PreviousValueValidator * pPrevious =(PreviousValueValidator *)pThis;
    if (val<pPrevious->previousValue)
    {
        return false;
    }
    pPrevious->previousValue = val;
    return true;
}
  
int buf[16];
RangeValidator validator = newRangeValidator(0, 9);
Stack   stack = newStackWithValidator(buf, &validator.base);

按照以下方法将RangeValidator 作为base使用即可扩展 RangeValidator


typedef struct
{
    RangeValidator base;
    //true 表示需要进行奇偶校验
    const bool needOddEventCheck;
    //false 表示必须是奇数
    const bool needToBeOdd;
}OddEventRangeValidator;
这样,C中就可以使用继承了!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值