EffectiveJava(17)要么为继承而设计,要么禁止继承
1.如果为了继承而设计类,那么该类必须有文档说明它可覆盖的方法的自用性.对于每个公有的
或受保护的方法或者构造器,它的文档必须指明该方法或者构造器调用了那些可覆盖的方法,是以
什么顺序调用的,每个调用的结果又是如何影响后续的处理过程的
–类必须通过某种形式提供适当的钩子,以便能够进入到它的内部工作流程中,这种形式可以是
精心选择的受保护的方法,也可以是受保护的域
–尽可能的减少暴露的成员
–对于为了继承而设计的类,唯一的测试方法就是编写子类
–构造器绝不能调用可被覆盖的方法,无论直接还是间接:超类的构造器在子类的构造器之前运行,所以
–子类中覆盖版本的方法依赖于子类构造器所执行的任何初始化工作
/**
* 构造器Sub没有机会初始化域date
* @author JacXuan
*
*/
public class Sub extends Super{
private final Date date;
Sub(){
date = new Date();
}
public void ovrrideMe(){
//如果ovrrideMe已经调用了date中的任何方法,当super构造器调用了ovrrideMe
//的时候,调用就会抛出NullPointException方法
System.out.println(date);
}
public static void main(String[] args) {
Sub sub = new Sub();
sub.ovrrideMe();
}
}
public class Super {
public Super(){
//如果ovrrideMe已经调用了date中的任何方法,当super构造器调用了ovrrideMe
//的时候,调用就会抛出NullPointException方法
ovrrideMe();
}
public void ovrrideMe(){
}
}
无论是clone还是readObject,都不可以调用可覆盖的方法:因为二者在行为上非常类似构造器
对于那些并非为了安全地进行子类化而设计和编写文档的类,要禁止子类化
2.程序文档:好的API文档应该描述一个给定的方法做了什么工作,而不是描述它是如何做到的
EffectiveJava(17)要么为继承而设计,要么禁止继承的更多相关文章
- Effective java第17条:要么为继承而设计,并提供文档说明,要么就禁止继承
不要过度设计. 面向对象编程,从一开始被洗脑难免在上手写代码时都会首先思考有没有公共方法啊,能不能把两个类抽象成一个父类再继承啊等,慎重使用继承,当要使用继承时一定要在文档注释中写明重写这个方法会给其 ...
- Effective Java 第三版——19. 如果使用继承则设计,并文档说明,否则不该使用
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Java:设计类的继承关系时的技巧
继承设计的技巧: (1)将公共操作和域放置在超类 (2)不要使用受保护的域 有些程序员认为,将大多数的实例域定义为protected是一个不错的主意,只有这样,子类才能够在需要的时候直接访问他们.然而 ...
- Python基础(17)_面向对象程序设计(抽象类、继承原理、封装、多态,绑定方法)
一.抽象类 抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化 1.在python中实现抽象类 import abc #利用abc模块实现抽象类 class All_file(metacl ...
- Effective C++ 第二版 40)分层 41)继承和模板 42)私有继承
条款40 通过分层来体现"有一个"或"用...来实现" 使某个类的对象成为另一个类的数据成员, 实现将一个类构筑在另一个类之上, 这个过程称为 分层Layeri ...
- C++ Primer 学习笔记_67_面向对象编程 --转换与继承、复制控制与继承
面向对象编程 --转换与继承.复制控制与继承 I.转换与继承 引言: 由于每一个派生类对象都包括一个基类部分,因此能够像使用基类对象一样在派生类对象上执行操作. 对于指针/引用,能够将派生类对象的指针 ...
- C++继承,多重继承,虚继承的构造函数以及析构函数的调用顺序问题
#include <iostream> using namespace std; class A{ int data_a; public: A(){ data_a = ; cout < ...
- python_way day10 python和其他语言的作用域 、 python2.7多继承和3.5多继承的区别 、 socket 和 socketserver源码(支持并发处理socket,多进程,多线程)
python_way day10 1.python的作用域和其他语言的作用域 2.python2.7多继承和3.5多继承的区别 3.socket和socketserver源码(并发处理socket) ...
- javascript实现继承3种方式: 原型继承、借用构造函数继承、组合继承,模拟extends方法继承
javascript中实现继承的三种方式:原型继承.借用构造函数继承.混合继承: /* js当中的继承 js中 构造函数 原型对象 实力对象的关系: 1 构造函数.prototype = 原型对象 2 ...
随机推荐
- java算法(一) 直接选择排序
一.基本概念 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置(注:要把最大最小的元素和起始的元素交换), 然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾.以 ...
- hdu1024 Max Sum Plus Plus的另一种解法
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1024 http://www.51nod.com/onlineJudge/questionCode.htm ...
- sql 取一张表的全部外键
select a.name as 约束名, object_name(b.parent_object_id) as 外键表, d.name as 外键列, object_name(b.reference ...
- VC++中有关句柄和指针及其转换(转)
原文转自 https://blog.csdn.net/jearmy/article/details/47030011 1.MFC窗口的句柄和指针的转换 (1) 一般窗口对象都会有一个其对应的句柄变量, ...
- MFC中使用sqlite3操作数据库
需要用到的文件有sqlite3.h .sqlite3.dll.sqlite3.lib.网上很多人分享下载地址这里不再赘述. 将这三个文件拷贝到自己新建MFC项目目录下,在解决方案窗口下 添加现有项,选 ...
- UVA 10334 Ray Through Glasses
自己手动画了第三项发现f[3]=5;就猜斐波那契了.实际上光线分为两种距离外界有2面玻璃,1面玻璃 其分别时n-1次反射,n-2次反射形成的 故推出斐波那契. 手动一些f1,f2,f3就OK #inc ...
- Ubuntu配置网络遇到的一些问题
Ubuntu配置网络遇到的一些问题 在配置Ubuntu网络时,曾遇到了一些问题.查找了一些博客,所幸都解决了.记录一下,以便日后查阅. 设置DNS sudo vim /etc/resolv.conf ...
- 【linux高级程序设计】(第十四章)TCP高级应用 3
控制socket文件描述符属性 1.set/getsockopt()修改socket属性 int getsockopt (int __fd, int __level, int __optname, v ...
- Fiddler抓包1-抓firefox上https请求【转载】
本篇转自博客:上海-悠悠 原文地址:http://www.cnblogs.com/yoyoketang/p/6538021.html 前言 fiddler是一个很好的抓包工具,默认是抓http请求的, ...
- Visual Studio跨平台开发(1):Hello Xamarin!
前言 应用程序发展的脚步, 从来没有停过. 从早期的Windows 应用程序, 到网络时代的web 应用程序, 再到近几年相当盛行的行动装置应用程序(Mobile Application), 身为C# ...