设计心得——如何应用继承

一、继承

学过面向对象编程的都知道,面向对象编程中一个重要的基础就是封装(Encapsulation),而明白了封装,下一步就是继承(Inheritance)。继承的定义很清晰,但在面向对象编程中怎么理解?这个就需要多动一下脑筋了。
大家都知道,人类进步的一个重要原因就是人类太懒,不想干重复的事情。现实世界也是如此,正如网上流行的“投胎是个技术活儿”,而且,股神巴菲特也有类似的话。所以要想深入理解继承就必须明白,继承是从哪里来的。它其实就是从现实世界映射过去的。人类的子女可以继承长辈的遗产,通过一种“懒”的方式,不劳而获的得到想要的东西(当然前提是这个遗产可以达到)。那么,在计算机世界中,是不是在某些情况下可以不必再辛苦的写一些代码,从而达到一些目的呢?这就是继承在面向对象编程中是非常重要的基础的原因。
子女拿到遗产后,可以继续走长辈的路,也可以开创新的路。同样的一百块,长辈可能用来存款,而子女可能用来投资。同样是吃饭,长辈可能爱吃肉而子女爱吃海鲜,凡此种种,不一而同。下面看一个简单的继承的例子:

class Base{
public:
virtual Test(){std::cout<<"this is Base!"<<std::endl;}
};
class derived:public Base{
public:
virtual Test()override{std::cout<<"this is Derived!"<<std::endl;}
};

看了上面的例子再结合现实世界的理解,对继承就基本清楚了。继承就是拿到父类的一切允许拿到的代码,它其实就是代码重用的一种手段,也就是常说的“is a” 。需要说明的是,本文不对继承的基本应用进行分析,如果有对继承的代码应用方式有不解的,可以参看相关的书籍。

二、继承的优点和缺点

继承在面向对象编程中很重要的一个原因就在于它提供了一种可扩展的代码重用机制,在面向对象编程的初期发展中,有着举足轻重的位置。但随着编程技术的发展,设计者们逐渐发现了它的问题,并在后续的编程和设计书籍中都提到了其风险和解决的方法。
1、继承的优点
a) 重用类似代码,防止重复代码的出现
b) 灵活的使用重写和覆盖,实现不同的功能,比较容易扩展
c) 可以动态的组织不同行为即多态
d) 提供了一致性的封装,接口友好
2、继承的缺点
a) 破坏了原始的封装,导致代码的细节被暴露,违反了设计原则
b) 增加了耦合,使父子类形成了较强的依赖性
c) 灵活的有限性,即只对继承相关体现了较好的灵活性而非继承关系的灵活扩展受到限制
d) 导致设计的复杂,特别是在多继承和较深层次的继承时,往往导致代码的维护难度
e) 父层类(多重继承时),可能产生不必要的代码依赖形成重复代码并限制扩展
f) 不合理的继承导致的代码的可维护性和可扩展性降低
3、解决继承的问题
a) 尽量减少使用继承,多使用组合等,非必要不继承
b) 严格限制继承的方法和属性,非必要不开放相关继承的方法和属性
c) 从设计层面替代继承,使用设计模式(如策略模式等)或模板等技术实现

三、应用场景

下面看一个基本的应用场景:

#include <iostream>
class Parent
{
public:
    Parent(){}
    ~Parent(){}
public:
    virtual void eat(int cost){std::cout<<"We spent "<<cost<<" yuan on meat for dinner!"<<std::endl;}
    virtual int invest(int money){
        std::cout<<"We have a deposit of "<< money<<" yuan!"<<std::endl;
        return money;
    }
};
class InheritanceExample : public Parent
{
public:
    InheritanceExample(){}
    ~InheritanceExample(){}
public:
    virtual void eat (int cost) override{
        std::cout<<"We spent "<<cost<<"  yuan on seafood for dinner!"<<std::endl;
    }
    virtual int invest(int money)override {
        std::cout<<"We bought  " <<money<<" shares of stocks!"<<std::endl;
        return money;
    }
};
void testInteritance(){
    Parent p;
    p.eat(100);
    InheritanceExample ie;
    ie.eat(200);
}
int main() {
    testInteritance();
    return 0;
}

通过这个简单的继承,实现了父辈与子辈对待投资和吃饭的不同的情形,能更好的理解继承的应用。

四、总结

一种技术如果不放到具体的场景中,谈不到优与劣,更谈不上对与错。技术的出现就是为了服务于现实的需求,如果脱离开这种需求技术的意义就没有多大了。如果实际的网络需求永远不会超过100K,那么光纤就可能不会被应用到网络传输上。
合适的是最好的,但要明白,这个合适是动态发展、不断变化的。与诸君共勉!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值