这一条是承接上一条的,所有为继承而设计的类都必须有充足的文档来精确地描述改写每一个方法所带来的影响。也就是要求文档中必须写明那些方法是要求改写的,那些是自用的。对于每一个公有或保护的方法或者构造函数,它的文档必须指明它调用了哪些可改写的方法,是以什么顺序调用的,每个调用结果又是如何影响后续的处理过程的。
这一条中需要特别注意的一段是:在为了继承而设计类的时候,Cloneable和Serializable接口表现出了特殊的困难。如果一个类是为了继承而设计的,那么无论实现其中哪个接口都不是一个好主意,因为它们把一些实质性的负担转嫁到了扩展这个类的程序员的身上。
看到这一段是最让我紧张的,因为我的那些转为继承而设计的类(甚至写成抽象类,可能又触犯了下一条),这两个接口都实现了!仔细研读过【第10条】和【第54条】后,我基本理解了上述结论的原因:
首先是Cloneable接口,【第10条】中已经降到了,再简单回顾一下:java.lang.Object对于clone的约定要求所有子类要首先调用超类的clone方法,然后修改那些需要修改的引用。换句话说就是要递归clone方法。这就是说不能再像equals、hashCode、toString方法那样仅在超类中实现,而子类无需改写了,所有实现了Cloneable接口的类都必须改写clone方法。加之【第10条】中所见到的,改写clone方法的复杂性(N多类型都只是影子克隆),所以这些困难就转移到了子类的实现者身上了。尤其对于团队开发,不能要求每一个开发者都是资深Java程序员呀。
再说说Serializable接口(详细分析稍后见【第54条】):为了保证兼容性,也就是说要保证由之前版本所序列化出来的字节流,能被之后的版本成功地反序列化,反之亦然。这就把你自己的灵活性限定死在私有成员这个很小的范围内了,在新版本中你不能增加新的公有域,也不能改变原公有方法的返回值。如果这个类是为继承而设计的,那么子类的实现者将会面临同样严格的约束,超类和子类的设计者同时被兼容性所禁锢。
在我的案例中,由于这些转为继承而设计的类都是JavaBean,所以Cloneable接口可以放弃了,使用org.apache.commons.beanutils.BeanUtils.cloneBean来替代clone。而Serializable接口是躲不开的,前后台的通讯还要靠它呢。那么怎么办呢?好在我所设计的Framework只是一个开发框架,而不是通用的技术框架,基本不可能有不同的子类在不同的Framework版本下编译的情况,也不可能有不同版本的class文件在两台服务器间通讯的情况。所以,我可以不受此约束所限,升级版本的时候大胆地修改那些公有成员。然而这只是个特例,甚至有的时候可能仅在一个项目内适用,如果你所设计的是一个通用的技术框架,那么请小心。加入JRE的作者不小心违反这一约定,那么可能相同的软件分别在不同版本JRE的服务器上运行,之间通讯时,就“对不上暗号了”。
【Effective Java 学习笔记】系列连载专题请见:
http://tonylian.iteye.com/categories/64208
分享到:
相关推荐
这份文档是关于JAVA语言程序设计的期末考试试题和答案解析,包含了多项选择题,主要考察学生对JAVA基础知识的掌握程度,包括语法、类与对象、循环控制、数据类型、数组、条件判断、运算符以及类的继承等核心概念。...
- **循环队列元素数量计算**:在一个循环队列中,如果`front`和`rear`均等于15,则该队列要么为空要么已满。因此,循环队列中的元素个数可能是0或35个。 ### 18. C 语言基础知识 - **C 语言常见误区**:在C语言中...
2. 在Word中设置页码,可以灵活控制是否在第一页显示页码,这是文档格式化的一部分。 3. 对于基类和派生类的关系,选项B是错误的,因为派生类继承了基类的属性,而不是基类继承派生类的属性。 4. MySQL的完整性...
`Sente`类实现了`Go`接口,`Goban`类继承了`Sente`类,同时`Stone`类继承了`Goban`类并也实现了`Go`接口。当调用`go()`方法时,会根据对象的实际类型执行相应的方法。由于`Sente`、`Goban`和`Stone`都实现了`Go`接口...
第五个元素E入栈前,栈中元素可以出栈。根据选项D(DCBEA),可以看出这是一个有效的出栈顺序,因为每次出栈都是从栈顶开始,符合LIFO原则。 ### 9. 关系模型中的“关系”的含义 在关系模型中,“关系”指的是我们...
**知识点**:数据库系统由数据库、软件和硬件组成,而“说明书”并不是其组成部分。 ### 20. 软件生命周期 **知识点**:软件生命周期涵盖了软件产品的整个过程,从需求分析、设计、实现、测试、部署到后期的维护和...
1) 第1章:对象入门 这一章是对面向对象的程序设计(OOP)的一个综述,其中包括对“什么是对象”之类的基本问题的回答,并讲述了接口与实现、抽象与封装、消息与函数、继承与合成以及非常重要的多形性的概念。...
《2023年精品电大数据库基础与应用形成性考核册答案带原题.doc》这份文档涵盖了数据库基础与应用的重要知识点,主要包括数据库的基本概念、关系数据库理论、数据模型、数据库设计以及数据库管理系统(DBMS)的功能。...
17. Java继承:Java允许类的继承,子类可以继承父类的属性和方法。 18. 判断三角形条件:三条边长A、B、C构成三角形的条件是任意两边之和大于第三边,并且每边长度大于0。 19. 静态数组定义:数组的下标通常从0...
- **代码示例**:提供的代码片段定义了一个名为`MyListener`的类,该类继承了`MouseAdapter`并实现了`mouseEntered`方法。 - **结论**:由于`MyListener`继承了`MouseAdapter`,因此不需要实现`MouseListener`接口中...
当给幻灯片应用了特定的设计模板后,该幻灯片将遵循设计模板的格式,而非幻灯片母版的格式。因此,正确的选项为 B:“使用设计模板的格式”。而 A、C、D 三个选项的描述都是不正确的。 ### 8. HTTP 协议交互过程 *...
- **问题描述**:给出一段Python代码,并询问其输出结果。 - **正确答案**:B - **知识点解析**:该题目考查了Python中列表的引用传递以及函数的作用域。在Python中,当一个列表被赋值给另一个变量时,实际上是创建...
根据提供的文档信息,我们可以归纳出一系列关于计算机二级等级考试的关键知识点。这些知识点涵盖了编程基础、数据库操作、Word应用、算法分析、数据结构、面向对象编程等多个方面。 ### 1. 静态方法访问权限 - **...
在 C 语言中,数组名可以被视为指向数组首元素的常量指针,但在传递给函数时,实际上是传递了一个指向数组的指针,而不是整个数组。 ### 15. 合法的标识符 在大多数编程语言中,标识符可以包含字母、数字和下划线...
工作区属性(虽然这个答案似乎不太符合常识,通常设置逻辑表会在表设计器或数据库设计器中进行,但题目给出的答案为B)。 ### 2. 数据独立性 - **知识点**: 数据独立性是指应用程序与存储在磁盘上的数据库中数据...
**第十五章:事务** - **定义**:事务是数据库中一系列操作的集合,这些操作要么全部成功,要么全部失败。 - **ACID特性**:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability...