【冒号课堂】【阅读笔记】OO的继承

软件设计应该兼顾灵活性与稳定性,提倡外静内动。外静指保持外部的接口不变,内动指允许内部的实现变动。无论是抽象还是设计模式以及库、框架、架构等的设计,无不将此奉为圭臬。

实现继承可能会破坏父类的封装,如访问父类的protected成员、暴露基础类、覆盖父类的方法。

实现继承最大的硬伤是在类族之间建立了强耦合关系,使代码趋于僵硬、脆落和复杂。

子类在覆盖父类某一方法时,不仅要保证该方法的规范,还要维持相应关联方法的规范,不能破坏父类规范之内的逻辑关联。

当祖先类不能在为后代类提供孤立于内部实现的私有接口时,前者的封装便会被破坏,其改动可能会牵连到后者,造成“脆落的基类”问题。

提倡接口继承,慎用实现继承。

非抽象类不适宜作基类。

为继承而设计的类应该做到:禁用protected域成员;保证protected方法成员的规范性和稳定性;防止覆盖的副作用。

非多态方法虽然不如多态方法灵活,但更稳定可靠,不仅能避免继承带来的安全漏洞和封装破坏,还可能带来性能上的改善。

当类的一个公有方法直接或间接调用了自身的另一个多态方法时,应特别谨慎。如果不能杜绝这类自用,那必须将其规范化,以免被子类错误地覆盖。此外,应尽量采用接口非虚原则来分离接口与挂钩: 让该公有方法不是多态的接口,让该多态方法不是公有的挂钩。

类的实例方法一般有4种用途(不排除一法多用):

  1. 为外界提供服务的公开接口
  2. 为子类提供展开点的内部回调
  3. 为子类或包提供服务的内部接口
  4. 为自身提供服务的私有接口

* 除内部回调外其他最好是非多态的

继承与组合的对比

  1. 继承是一种静态显性的关系,而组合是一种动态隐性的关系。
  2. 实现继承是灰盒复用,而组合是黑盒复用。
  3. 多重继承通常不被支持或不被提倡,而多重组合则不然。
  4. 继承是对基础类的兼收并蓄,而组合是对基础类的批判继承。

组合强调整体与部分之间静态结构上的关系,委托转发强调外部接口与内部实现之间动态分离。

时间: 2024-08-03 09:07:31

【冒号课堂】【阅读笔记】OO的继承的相关文章

Hadoop阅读笔记(六)——洞悉Hadoop序列化机制Writable

酒,是个好东西,前提要适量.今天参加了公司的年会,主题就是吃.喝.吹,除了那些天生话唠外,大部分人需要加点酒来作催化剂,让一个平时沉默寡言的码农也能成为一个喷子!在大家推杯换盏之际,难免一些画面浮现脑海,有郁闷抓狂的,有出成果喜极而涕的,有不知前途在哪儿的迷茫与不安……总的来说,近一年来,不白活,不虚度,感触良多,不是一言两语能说得清道的明的,有时间可以做个总结,下面还是言归正传谈技术吧. 上篇在了解了Hadoop的目录和源码结构后,说好的要啃源码的,那就得啃.也感谢一直以来关注我.支持我的网友

《STL源码剖析》---stl_tree.h阅读笔记

STL中,关联式容器的内部结构是一颗平衡二叉树,以便获得良好的搜索效率.红黑树是平衡二叉树的一种,它不像AVL树那样要求绝对平衡,降低了对旋转的要求,但是其性能并没有下降很多,它的搜索.插入.删除都能以O(nlogn)时间完成.平衡可以在一次或者两次旋转解决,是"性价比"很高的平衡二叉树. RB-tree(red black tree)红黑树是平衡二叉树.它满足一下规则 (1)每个节点不是红色就是黑色. (2)根节点是黑色. (3)如果节点为红色,则其子节点比为黑色. (4)任何一个节

《STL源码剖析》---stl_iterator.h阅读笔记

STL设计的中心思想是将容器(container)和算法(algorithm)分开,迭代器是容器(container)和算法(algorithm)之间的桥梁. 迭代器可以如下定义:提供一种方法,能够依序寻访某个容器内的所有元素,而又无需暴露该容器的内部表达方式. 在阅读代码之前,要先了解一个新概念:Traits编程技法 template <class T> struct MyIter { typedef T value_type //内嵌型别声明 T *ptr; MyIter(T *p = 0

socketserver.py代码阅读笔记

socketserver.py源码阅读笔记 前言 一直想弄清楚一个http server和Web框架的工作原理.但以我目前的实力,阅读一个http server或web框架代码还是太难了.后来又对异步IO.并发产生的兴趣.前几天做一个大作业需要写几个各种不同并发模型的TCP Server,写完才想起Python有现成的socketsever模块可以用,完全不需要自己写.于是对比了一下我写的代码和socketsever.py,发现我写的真没socketsever写的好.我的代码经验还是太少了.于是

JS学习笔记-OO疑问之封装

封装是面向对象的基础,今天所要学习的匿名函数与闭包就是为了实现JS的面向对象封装.封装实现.封装变量,提高数据.系统安全性,封装正是面向对象的基础. 匿名函数 即没有名字的函数,其创建方式为 function(){...} 单独存在的匿名函数,无法运行,可通过赋值给变量调用或通过表达式自我执行来实现运行. 1.赋值给变量为一般的函数使用方式 var run = function(){ return '方法运行中'; }; alert(run()); 2.通过表达式自我执行 (function(a

什么时候该重构--《重构》阅读笔记

当出现以下问题的时候,就要开始重构代码. 1)重复代码 重复代码在业务逻辑相同的地方,抽成方法.重复代码在业务逻辑不同的地方.抽成类. 2)long method 其实这个问题很多时候都碰到.我觉得原因主要还是两个.一个是修bug的时候,不敢改.因为这玩意,要改的话,压力还是很大的.还有一个写好之后,懒的改.这一种,特别实在这一次看书的过程中,觉得重构完全可以发生在刚写好代码的时候.因为我们写代码的时候,本能就是先实现功能.然后再考虑代码改如何组织. 3)large class 同上. 4)lo

《STL源代码剖析》---stl_deque.h阅读笔记(2)

看完,<STL源代码剖析>---stl_deque.h阅读笔记(1)后.再看代码: G++ 2.91.57,cygnus\cygwin-b20\include\g++\stl_deque.h 完整列表 /* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation f

Effective C++ 阅读笔记_条款27 尽量少做转型动作

Effective C++ 阅读笔记_条款27 尽量少做转型动作 1.转型的三种形式,可以分为两大类. (1)旧式转型(old-style casts) (1.1) (T) expresstion (1.2) T (expression) (2) 新式转型(c++-style casts) (2.1)const_cast<T> (expression) (2.2)dynamic_cast<T> (expression) (2.3)reinterpret_cast<T>

《STL源码剖析》---stl_deque.h阅读笔记(2)

看完,<STL源码剖析>---stl_deque.h阅读笔记(1)后,再看代码: G++ 2.91.57,cygnus\cygwin-b20\include\g++\stl_deque.h 完整列表 /* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation fo

《STL源码剖析》---stl_list.h阅读笔记

STL中链表list是一个常用的容器.list在内存中是不连续的双向链表,且是环形的.要了解链表细节是如何操作的话,阅读STL关于链表的代码是最好的方法. G++ 2.91.57,cygnus\cygwin-b20\include\g++\stl_list.h 完整列表 /* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this