C++编程规范之37:公用继承即可替换性。继承,不是为了重用,而是为了被重用

摘要:

    知其然:公用继承能够使基类的指针或者实际引用指向某个派生类的对象,既不会破坏代码的正确性,也不需要改变已有的代码。

    还要知其所以然:不要通过公用继承重用(基类中的已有)代码,公用继承是为了被(已经多态地使用了基对象的已有代码)重用的。

    按照Liskov替换原则(LiskovSubstitution Principle),公用继承所建模的必须总是“是一个(is-a)”关系:所有基类约定必须满足这一点,因此如果依靠成功地满足基类的约定,所有虚拟成员函数的改写版本就必须不多于其基类版本,其承诺的也必须不少于其基类版本。使用指向Base的指针或者引用的代码必须能正确工作,即使指针或者应用实际上指向的是Derived。

    继承的误用将破坏正确性。没有被正确实现的继承大多数都会无法遵守基类确定的显式或者隐式约定而迷乱。这种约定可能是很微妙的,如果无法在代码中直接表达,程序员就必须格外小心。

    公用继承的目的是实现可替换性,公用继承的目的并不是为了派生类重用积累的代码,从而用基类代码实现自己。这种“用……来实现”的关系可能完全没有问题,但是应该用组合关系来建模——或者仅仅在某些特殊情况下,通过非公用继承来实现。

    还可以用另一种说法来表述:当动态多态正确而且适合时,组合是自私的,而继承是慷慨的。心的派生类是已有通用抽象的新特例。已有的动态代码通过调用Base的虚拟函数来使用Base&或者Base*,应该能够无缝地使用继承自Base的MyNewDerivedType的对象。心的派生类型向已有代码中添加新功能时,不需要修改已有代码,而是可以在加入新派生对象时无缝地增加其功能。

    新的需求应该很自然地由新代码满足,心的需求不应该导致对已有代码的重新改写。

在面向对象技术出现之前,新代码掉哟个已有代码就一直很容易。尤其是公用继承使已有代码安全无缝地调用新代码变得更加容易了。

时间: 2024-07-30 07:20:16

C++编程规范之37:公用继承即可替换性。继承,不是为了重用,而是为了被重用的相关文章

JAVA 编程规范

编程|规范 1. 应用范围 本规范应用于采用J2EE规范的项目中,所有项目中的JAVA代码(含JSP,SERVLET,JAVABEAN,EJB)均应遵守这个规范.同时,也可作为其它项目的参考. 2. 设计类和方法 2.1 创建具有很强内聚力的类 方法的重要性往往比类的重要性更容易理解,方法是指执行一个统一函数的一段代码.类常被错误的视为是一个仅仅用于存放方法的容器.有些开发人员甚至把这种思路作了进一步的发挥,将他们的所有方法放入单个类之中. 之所以不能正确的认识类的功能,原因之一是类的实现实际上

C#编程规范和惯例

编程|规范 谁都会写代码!几个月的编程经验可以让你写出"可运行应用程序".让它可运行容易,但是以最有效率的方式编码就需要下更多的功夫! 要知道,大多数程序员在写"可运行代码,"而不是"高效代码".我们在这个指南课程前面提到,你想成为你们公司"最尊贵的专业人员"吗?写"高效代码"是一项艺术,你必须学习和实践它. 命名惯例和规范 注记 : Pascal 大小写形式-所有单词第一个字母大写,其他字母小写.Came

IDesign C#编程规范(二)

编程|规范 续之一,小鸡射手接着翻译了IDesign编码规范的第二章前部. 2 编码惯例 Coding Practices 1. 避免在一个文件中放多个类. Avoid putting multiple classes in a single file. 2. 一个文件应该只对一个命名空间提供类型.避免在同一文件中有多个命名空间. A single file should only contribute types to a single namespace. Avoid having mult

IOS团队编程规范

本文讲的是IOS团队编程规范,需求是暂时的,只有变化才是永恒的,面向变化编程,而不是面向需求编程. 不要过分追求技巧,降低程序的可读性. 简洁的代码可以让bug无处藏身.要写出明显没有bug的代码,而不是没有明显bug的代码. 先把眼前的问题解决掉,解决好,再考虑将来的扩展问题. 一.命名规范 1.统一要求 含义清楚,尽量做到不需要注释也能了解其作用,若做不到,就加注释,使用全称,不使用缩写. 2.类名 大驼峰式命名:每个单词的首字母都采用大写字母 ==例:== MFHomePageViewCo

《C++编程规范:101条规则、准则与最佳实践》——第2章设计风格设计风格 C++编程规范:101条规则、准则与最佳实践 复杂性啊,愚人对你视而不见,实干家受你所累。 有些人避而远之。惟智者能够善加消除。 ——Alan Perlis 我知道,但是却又忘记了Hoare的至理名言:不成熟的优化是程

第2章设计风格 C++编程规范:101条规则.准则与最佳实践 复杂性啊,愚人对你视而不见,实干家受你所累. 有些人避而远之.惟智者能够善加消除. --Alan Perlis 我知道,但是却又忘记了Hoare的至理名言:不成熟的优化是程序设计中的万恶之源. --Donald Knuth[1] The Errors of TeX[Knuth89] 完全区分设计风格与编码风格是非常困难的.我们将一般在实际编写代码时才用得到的条款留到下一部分介绍. 本部分集中讨论适用面比一个特定的类或者函数更广的原则和

《C++编程规范:101条规则、准则与最佳实践》——第一章组织和策略问题1.1不要拘泥于小节 (又名:了解哪些东西不应该标准化)

第一章组织和策略问题 C++编程规范:101条规则.准则与最佳实践如果人们按照程序员编程的方式修建房屋,那么一只啄木鸟就能毁灭整个文明. --Gerald Weinberg[1] 为了遵从C和C++的伟大传统,我们从0开始编号.首要的指导原则,也就是第0条,阐明了我们认为对编程规范而言最为基本的建议. 接下来,这个导论性部分的其他条款将主要讲述几个精心选择的基本问题,这些问题大多数与代码本身并没有直接关系,它们讨论的是编写坚实代码所必需的工具和技术. 本部分中我们选出的最有价值条款是第0条:"不

实现高效Java编程规范的十一条基础规则

编程|规范 本文介绍的Java规则的说明分为5个级别,级别1是最基本也是最重要的级别,在今后将陆续写出其他的规则.遵守了这些规则可以提高程序的效率.使代码有更好的可读性等. (1) 避免使用NEW关键字来创建String对象 把一个String常量copy到String 对象中通常是多余.浪费时间的. Public class test{ Public void method(){ System.out.print (str); } private String str = new String

C# 编程规范

编程|规范 C# 编码规则 一.命名 1.用pascal规则来命名方法和类型. public class TextBox { public void DataBind() { } } 2.用camel规则来命名局部变量和方法的参数. string userName; public AddUser(string userId, byte[] password); 3.所有的成员变量前加前缀 _ public class Database { private string _connectionSt

Visual Basic编程规范

visual|编程|规范 Visual Basic编程规范 1.      Visual Basic IDE(集成开发环境)设置        必须打开设置选项的"要求变量声明","对齐控件到网格","自动缩进"开关.        Tab的宽度统一为4个空格,网格单位一律设为:width 60 height 60. 2.     命名约定        (注意:在任何时候,不能使用中文及全角字符,只允许使用英文字母.下划线和数字) 2.1