论坛首页 Java企业应用论坛

CoreJava: 第一次用LinkedHashSet带来的思考(二)

浏览 1936 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-02-15  
OO


    在第一次用LinkedHashSet带来的思考(一) 中,顺着 LinkedHashSet的保序功能是怎么实现这一问题看了HashSet源码, 注意到HashSet的一个构造方法前没有写访问修饰符, 这样也就只有跟HashSet在同一个包的类才能访问这个构造方法了. 为了下面的谈论方便,我们将这种没写访问修饰符的情况称为"包修饰符",当然也有叫"默认修饰符"的,但个人觉得还是这个"包修饰符"较好些, 可以从名字上看出它的作用来.

    突然间觉得这种处理很巧妙: 原来在HashSet里边深藏着一个LinkedHashSet!真是藏在深闺无人知呀!在这个"包修饰符"修饰的构造方法的帮助下,  LinkedHashSet的实现就显得很干净简洁了.
    但不免会想, 有没有必要把LinkedHashSet的功能实现放到父类呢? 在自身类里不行吗? 若在自身类里, 别的类如想有同样的功能而简单地copy/paste也不想用"hasA"的组合方式的话, 就只能继承LinkedHashSet, 那样继承太深, 写在HashSet类里, 继承层次上会少些. 这样解释对不? 看来这OO设计中,在处理继承上有很多考虑的地方, 而平时做项目的工作中也很少体会到.


    上面是很干瘪地写了些关于HashSet里那个"包修饰符"构造方法的思考, 写的很难受, 根本原因是自己对这个的理解不对位,也就没能剥茧抽丝地把这个概念下的东西说清楚. 下面我试着描述下LinkedHashSet实现过程中所体现的"HasA"的组合方式.
    我们知道除copy/paste外, 正规军里的做法有继承和组合, 也就是"isA"和"hasA". 不过在设计实践中, 有这样的说法, 若只是为了代码重用的话, 尽量地用hasA的组合的方式. 一般而言, 在选择isA还是hasA时, 有如下参考:
        1, 不要仅仅为了代码重用而用isA的继承, 而用hasA的组合方式重用代码. 若用isA的继承, 当父类有什么改变时,子类就受到很大的牵连.
        2, 不要仅仅为了多态而用isA的继承,而用接口加组合方式.
    现在结合HashSet的实现, 看这两点的应用.HashSet内部用一个HashMap来作为数据的最终存放地,  它并没有继承HashMap类. 从另一方面来说, 为了实现多态, HashSet实现了Set接口.

    见的很糟, 比自己的预期差不少. .....

论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics