103.区分组合和继承的应用场合

继承所带来的多态性虽然是面向对象的一个重要特性,但这种特性不能在所有的场合中滥用。继承应该被当做设计架构的有用补充,而不是全部。

组合不能用于多态,但组合使用的频率却要远远高于继承。

继承UML图如下:

对应的代码如下:

abstract class Stream
    {
        //省略
    }

    class FileStream:Stream
    {
        //省略 
    }

    class MemoryStream : Stream
    {
        //省略
    }

组合UML图如下:

对应代码如下:

    class Context
    {
        //省略
    }

    class CultureInfo
    {
        //省略
    }

    class Thread
    {
        private Context m_Context;
        private CultureInfo m_CultureInfo;
        //省略
    }    

从设计的角度来看,继承代表的是“Is a”,组合代表的是“Has a”。FileStream和MemoryStream都是(Is a)Stream,而对于线程Thread来说,它拥有(Has a)线程上下文Context和区域信息CultureInfo。这是最重要的区别,任何时候,设计理念上的因素总是排在第一位。

继承不仅仅是指继承自某个类型(class),也可以指继承自某个接口(interface)。继承最大的优点就是多态,这也奠定了面向抽象编程的基础。继承提高了代码的复用性。组合显然不具备这种特性。

从语法角度来看,继承易于扩展。基类一旦扩展一个具有public、internal、protected访问修饰符的接口,所有的子类都会自动拥有其接口,组合则不能。组合要拥有任何对象的行为,必须手动编码。以Thread为例,组合要拥有CultureInfo的行为,必须首先在自身内部包含一个CultureInfo字段,如下:

    class CultureInfo
    {
        //省略
        public void OtherMethod()
        {
            
        }
    }

    class Thread
    {
        private Context m_Context;
        private CultureInfo m_CultureInfo;
        //省略

        public void OtherMethod()
        {
            m_CultureInfo.OtherMethod();
        }
    }    

到目前为止,似乎一直在说继承的优点。事实上,继承的以上优点,正好又是它的缺点。子类天然具有基类的公开接口,而这正好破坏了面向对象的“封装性”。我们显然不需要每一层的类型都具有上层的所有接口。一个类,如果其继承体系达到3层(当然,凡事都有例外,WPF体系中的控件集成体系,以Shape为例,多达7层),就可以考虑停止了。如果不停止,对调用者来说,最底层的类型会有多少公开的方法和属性呢?答案是最底层的类型会拥有所有上层类型的开放接口。随着项目的发展,组合的优势会逐渐体现出来,它良好的封装性使类型可以对外宣布:我只做一件事。

组合的另一个优势是,它可以组合多个其他类型。如果组合太多的类型,就意味着当前的类很可能做了太多的事情,它就需要拆分成两个类了。继承不具有这样的特性,在C#中,子类只能有一个基类(接口则放开这种限制,子类可以继承自多个接口)。

应当根据实际情况考虑是使用继承还是组合。一般来讲,组合更能满足大部分的应用场景。不要为了让代码看起来像“面向对象”,而滥用继承。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值