Effective Java笔记(19)要么设计继承并提供文档说明,要么禁止继承

华硕笔记本键盘失灵恢复方法全解析 华硕笔记本键盘失灵问题可能由多种原因导致,但大多数问题都可以通过上述方法得到解决。在尝试恢复键盘功能时,请务必按照步骤操作,并注意备份重要数据。如果问题依然存在,请寻求专业维修人员的帮助。希望本文能够帮助大家快速解决华硕笔记本键盘失灵的问题! 阅读详情

        对于专门为了继承而设计并且具有良好文档说明的类而言,意味着什么呢?

        首先,该类的文档必须精确地描述覆盖每个方法所带来的影响 。 换句话说,该类必须有文档说明它可覆盖的方法的自用性。对于每个公有的或受保护的方法或者构造器,它的文档必须指明该方法或者构造器调用了哪些可覆盖的方法,是以什么顺序调用的,每个调用的结果又是如何影响后续处理过程的(所谓可覆盖( overridable)的方法,是指非 final的、公有的或受保护的)。更广义地说,即类必须在文档中说明,在哪些情况下它会调用可覆盖的方法 。 例如,后台的线程或者静态的初始化器(initializer)可能会调用这样的方法 。

如果方法调用到了可覆盖的方法,在它的文档注释的末尾应该包含关于这些调用的描述信息。这段描述信息是规范的一个特殊部分,写着:“Implementation Requirements”(实现要求..... ),它由Javadoc标签@implSpec生成。这段话描述了该方法的内部工作情况。下面举个例子,摘自java.util. AbstractCollection的规范:

public boolean remove(Object o)

(如果这个集合中存在指定的元素,就从中删除该指定元素中的单个实例(这是项可选的操作)。更广义地说,即如果集合中包含一个或者多个这样的元素e,就从中删除掉一个,如objects.equals(o,e)。如果集合中包含指定的元素,就返回true(如果调用的结果改变了集合,也是y一样)。
实现要求:该实现遍历整个集合来查找指定的元素。如果它找到该元素,将会利用迭代器的remove方法将之从集合中删除。注意,如果由该集合的iterator方法返回的迭代器没有实现remove方法,该实现就会抛出UnsupportedOperationException。)

        这份文档清楚地说明了,覆盖iterator方法将会影响remove方法的行为。而且,它确切地描述了iterator方法返回的Iterator的行为将会怎样影响remove方法的行为。与此相反的是,在第18条的情形中,程序员在子类化HashSet的时候,无法说明覆盖add方法是否会影响addAll方法的行为。

        关于程序文档有句格言:好的API文档应该描述一个给定的方法做了什么工作,而不是描述它是如何做到的。那么,上面这种做法是否违背了这句格言呢?是的,它确实违背了!这正是继承破坏了封装性所带来的不幸后果。所以,为了设计一个类的文档,以便它能够被安全地子类化,你必须描述清楚那些有可能未定义的实现细节。@implSpec标签是在Java 8中增加的,在Java9中得到了广泛应用。这个标签应该是默认可用的,但是到Java 9, Javadoc 工具仍然把它忽略,除非传人命令行参数: -tag"apiNote:a:API Note:”。

为了继承而进行的设计不仅仅涉及自用模式的文档设计。为了使程序员能够编写出更加有效的子类,而无须承受不必要的痛苦,类必须以精心挑选的受保护的( protected )方法的形式,提供适当的钩子(hook),以便进入其内部工作中。这种形式也可以是罕见的实例,或者受保护的域。例如,以java.util.AbstractList中的removeRange方法为例:

protected void removeRange(int fromIndex, int toIndex)

        (从列表中删除所有索引处于fromIndex (含)和toIndex (不含)之间的元素。将所有符合条件的元素移到左边(减小它们索引)。这一调用将从ArrayList中删除从toIndex到fromIndex之间的元素。(如果toIndex == fromIndex,这项操作就无效。)

        这个方法是通过clear操作在这个列表及其子列表中调用的。覆盖这个方法来利用列表实现的内部信息,可以充分地改善这个列表及其子列表中的clear操作的性能。

        实现要求:这项实现获得了一个处在fromIndex之前的列表迭代器,并依次地,重复调用ListIterator.next和ListIterator.remove,直到整个范围都被移除为止。注意:如果ListIterator.remove需要线性的时间,该实现就需要平方级的时间。
        参数:
                fromIndex要移除的第一个元素的索引。
                toIndex要移除的最后一个元素之后的索引。)

        这个方法对于List实现的最终用户并没有意义。提供该方法的唯一目的在于,使子类更易于提供针对子列表( sublist)的快速clear方法。如果没有removeRange方法,当在子列表( sublist)上调用clear方法时,子类将不得不用平方级的时间来完成它的工作。否则,就得重新编写整个subList机制——这可不是一件容易的事情!

        因此,当你为了继承而设计类的时候,如何决定应该暴露哪些受保护的方法或者域呢?遗憾的是,并没有什么神奇的法则可供你使用。你所能做到的最佳途径就是努力思考,发挥最好的想象,然后编写一些子类进行测试。你应该尽可能地少暴露受保护的成员,因为每个方法或者域都代表了一项关于实现细节的承诺。另一方面,你又不能暴露得太少,因为漏掉的受保护方法可能会导致这个类无法被真正用于继承。

        对于为了继承而设计的类,唯一的测试方法就是编写子类。如果遗漏了关键的受保护成员,尝试编写子类就会使遗漏所带来的痛苦变得更加明显。相反,如果编写了多个子类,并且无一使用受保护的成员,或许就应该把它做成私有的。经验表明,3个子类通常就足以测试一个可扩展的类。除了超类的程序设计者之外,都需要编写一个或者多个这种子类。

        在为了继承而设计有可能被广泛使用的类时,必须要意识到,对于文档中所说明的自用模式( self-use pattern), 以及对于其受保护方法和域中所隐含的实现策略,你实际上已经做出了永久的承诺。这些承诺使得你在后续的版本中提高这个类的性能或者增加新功能都变得非常困难,甚至不可能。因此,必须在发布类之前先编写子类对类进行测试。

        还要注意,因继承而需要的特殊文档会打乱正常的文档信息,正常的文档信息是被设计用来让程序员可以创建该类的实例,并调用类中的方法。几乎还没有适当的工具或者注释规范,能够把“普通的API文档”与“专门针对实现子类的程序员的信息”区分开。

为了允许继承,类还必须遵守其他一些约束。构造器决不能调用可被覆盖的方法,无论是直接调用还是间接调用。如果违反了这条规则,很有可能导致程序失败。超类的构造器在子类的构造器之前运行,所以,子类中覆盖版本的方法将会在子类的构造器运行之前先被调用。如果该覆盖版本的方法依赖于子类构造器所执行的任何初始化工作,该方法将不会如预期般执行。为了更加直观地说明这一点,下面举个例子,其中有个类违反了这条规则:

public class Super {

    public Super() {
        overrideMe() ;
    }
    public void overrideMe() {
    }
}

下面的子类覆盖了方法overrideMe,Super唯一的构造器就错误地调用了这个方法:

public final class Sub extends Super {

    private final Instant instant;
    Sub() {
        instant = Instant.now() ;
    }

    @Override 
    public void overrideMe() {
        System.out.println(instant);
    }
    public static void main(String[] args) {
        Sub sub = new Sub();
        sub.overrideMe();
    }
}

        你可能会期待这个程序会打印两次日期,但是它第一次打印出的是null,因为overrideMe方法被Super构造器调用的时候,构造器Sub还没有机会初始化instant域。注意,这个程序观察到的final域处于两种不同的状态。还要注意,如果overrideMe已经调用了instant中的任何方法,当Super构造器调用overrideMe的时候,调用就会抛出NullPointerException异常。如果该程序没有抛出NullPointerException异常,唯一的原因就在于println方法可以容忍null参数。

        注意,通过构造器调用私有的方法、final 方法和静态方法是安全的,这些都不是可以被覆盖的方法。

        在为了继承而设计类的时候,Cloneable 和Serializable接口出现了特殊的困难。如果类是为了继承而设计的,无论实现这其中的哪个接口通常都不是个好主意,因为它们把一些实质性的负担转嫁到了扩展这个类的程序员身上。然而,你还是可以采取一些特殊的手段,允许子类实现这些接口,无须强迫子类的程序员去承受这些负担。

        如果你决定在一个为了继承而设计的类中实现Cloneable或者Serializable接口,就应该意识到,因为clone和readObject方法在行为上非常类似于构造器,所以类似的限制规则也是适用的:无论是clone还是readObject,都不可以调用可覆盖的方法,不管是以直接还是间接的方式。对于readObject方法,覆盖的方法将在子类的状态被反序列化( deserialized)之前先被运行;而对于clone方法,覆盖的方法则是在子类的clone方法有机会修正被克隆对象的状态之前先被运行。无论哪种情形,都不可避免地将导致程序失败。在clone方法的情形中,这种失败可能会同时损害到原始的对象以及被克隆的对象本身。例如,如果覆盖版本的方法假设它正在修改对象深层结构的克隆对象的备份,就会发生这种情况,但是该备份还没有完成。

        最后,如果你决定在一个为了继承而设计的类中实现Serializable接口,并且该类有一个readResolve或者writeReplace方法,就必须使readResolve或者writeReplace成为受保护的方法,而不是私有的方法。如果这些方法是私有的,那么子类将会不声不响地忽略掉这两个方法。这正是“为了允许继承,而把实现细节变成-一个类的API的一部分”的另-种情形。

        到现在为止,结论应该很明显了:为了继承而设计类,对这个类会有一些实质性的限制。这并不是很轻松就可以承诺的决定。在某些情况下,这样的决定很明显是正确的,比如抽象类,包括接口的骨架实现( skeletal implementation) 。但是,在另外一些情况下,这样的决定却很明显是错误的,比如不可变类。

        但是,对于普通的具体类应该怎么办呢?它们既不是final 的,也不是为了子类化而设计和编写文档的,所以这种状况很危险。每次对这种类进行修改,从这个类扩展得到的客户类就有可能遭到破坏。这不仅仅是个理论问题。对于一个并非为了继承而设计的非final 具体类,在修改了它的内部实现之后,接收到与子类化相关的错误报告也并不少见。

        这个问题的最佳解决方案是,对于那些并非为了安全地进行子类化而设计和编写文档的类,要禁止子类化。有两种办法可以禁止子类化。比较容易的办法是把这个类声明为final的。另一种办法是把所有的构造器都变成私有的,或者包级私有的,并增加一些公有的静态工厂来替代构造器。这两种办法都是可以接受的。这条建议可能会引来争议,因为许多程序员已经习惯于对普通的具体类进行子类化,以便增加新的功能设施,比如仪表功能( 如计数显示等)、通知机制或者同步功能,或者为了限制原有类中的功能。如果类实现了某个能够反映其本质的接口,比如Set、List或者Map,就不应该为了禁止子类化而感到后悔。第18条中介绍的包装类( wrapper class)模式
还提供了另一种更好的办法,让继承机制实现更多的功能。

        如果具体的类没有实现标准的接口,那么禁止继承可能会给某些程序员带来不便。如果你认为必须允许从这样的类继承,一种合理的办法是确保这个类永远不会调用它的任何可覆盖的方法,并在文档中说明这一点。换句话说,完全消除这个类中可覆盖方法的自用特性。这样做之后,就可以创建“能够安全地进行子类化”的类。覆盖方法将永远不会影响其他任何方法的行为。

        你可以机械地消除类中可覆盖方法的自用特性,而不改变它的行为。将每个可覆盖方法的代码体移到一个私有的“辅助方法”(helper method)中,并且让每个可覆盖的方法调用它的私有辅助方法。然后用“直接调用可覆盖方法的私有辅助方法”来代替“可覆盖方法的每个自用调用”。

        简而言之,专门为了继承而设计类是一件很辛苦的工作。你必须建立文档说明其所有的自用模式,并且一旦建立了文档,在这个类的整个生命周期中都必须遵守。如果没有做到,子类就会依赖超类的实现细节,如果超类的实现发生了变化,它就有可能遭到破坏。为了允许其他人能编写出高效的子类,还你必须导出一个或者多个受保护的方法。除非知道真正需要子类,否则最好通过将类声明为final,或者确保没有可访问的构造器来禁止类被继承。

24、流化催化裂化的分子建模 本文探讨了流化催化裂化(FCC)的分子建模方法,重点分析了如何通过机理建模和模型修剪策略(如反应规则和随机规则)来减少计算复杂度,同时保持化学意义。文章还介绍了定量结构反应性关联(QSRC)在动力学参数确定中的应用,以及结焦对催化剂活性的影响。通过这些方法,FCC反应模型能够在预测产物分布的同时,显著提高计算效率。 阅读详情

相关推荐

WSL2+Docker实战:在Windows上部署MinerU 2.5.3,解锁媲美Demo的VLM PDF解析能力

本文详细介绍了如何在Windows系统上通过WSL2+Docker部署MinerU 2.5.3,实现媲美Demo的VLM PDF解析能力。文章涵盖环境准备、Docker部署实战技巧及高级使用技巧,特别针对PDF识别中的复杂排版、公式和图表处理提供了优化方案,帮助用户高效处理学术论文和技术文档。

weixin_29291573的博客 482

第19 条:要么设计继承并提供文档说明,要么禁止继承

要么设计继承并提供文档说明,要么禁止继承 该类的文档必须精确地描述覆盖每个方法所带来的影响 对于非私有方法包括构造器的文档说明上必须标注这个方法调用了哪些可以被覆盖的类,是什么顺序调用的,调用结果是怎么影响后续方法处理的。可以被覆盖的类是指非final的、公有的、受保护的方法,后台线程或者静态初始化器可能会调用可被覆盖的方法。 调用的方法的文档末尾会有调用描述信息,写着: “ Implementa...

weixin_44130081的博客 284

Win10 / Win11 启用 Hyper-V 虚拟机详细教程(图文+命令行全攻略)

摘要:本文详细介绍Windows10/11系统启用Hyper-V虚拟化平台的方法,包含专业版/企业版的图形界面和PowerShell命令行操作,以及家庭版通过脚本强制启用的特殊方案。内容涵盖版本支持对比、操作步骤图解、常见问题解答和性能优化建议,帮助开发者快速搭建虚拟化环境进行多系统测试。附微软官方文档参考链接和详细操作示意图。

ElioXu 7068

Effective Java读书笔记-6

Effective Java读书笔记-6使可变性最小化复合优先于继承要么设计继承并提供文档说明,要么禁止继承 使可变性最小化 不可变类是指其实例不能被修改的类。每个实例中包含的所有信息都必须在创建该实例的时候就提供,并在对象的整个生命周期(lifetime)内固定不变。不可变的类比可变类更加易于设计、实现和使用。它们不容易出错,且更加安全。为了使类成为不可变,要遵循下面五条规则: 1.不要提供任何会修改对象状态的方法(也称为设值方法)。 2.保证类不会被扩展。 为了防止子类化,一般做法是声明这个类成为fin

weixin_42583701的博客 227

西门子1500T插补控制实战:从硬件组态到轨迹规划

本文详细解析了西门子1500T插补控制的完整实战流程。从硬件组态中正确选择带T的CPU和配置报文105,到创建同步轴与插补器工艺对象,再到使用MC_Interpolator功能块编程实现直线与圆弧插补,并分享了调试技巧与常见问题解决方案,为工程师实现高精度复杂轨迹规划提供清晰指导。

weixin_29228781的博客 423

别再瞎调参数了!分子动力学模拟新手必看的力场选择与验证实战指南

本文为分子动力学模拟新手提供力场选择与验证的实战指南,详细解析主流力场特性及适用场景,并通过水分子案例演示完整的验证流程。文章重点对比SPC/E、TIP3P和OPLS-AA三种力场在GROMACS中的表现,帮助读者避免常见参数调整误区,提升模拟准确性。

weixin_26934905的博客 425

建议:要么为继承而设计,并提供文档说明,要么就禁止继承。

首先,该类的文档必须精确地描述覆盖每个方法所带来的影响。换句话说,该类必须有文档说明他可覆盖(override)的方法的自用性(self-use)。对于每个公有的或受保护的方法或者构造器,它的文档必须指明该方法或者构造器调用了哪些可覆盖的方法,是以什么顺序调用的,每个调用的结果又是如何影响后续的处理过程的(所谓可覆盖(override)的方法,是指非final的,公有的或受保护的)。更一般的,类必...

孤芳不自赏 399

扫地机器人:从仿真到决策,一个完整SLAM导航系统的自研之路

本文详细记录了从零开始自研扫地机器人SLAM导航系统的全过程,涵盖ROS-Gazebo仿真系统搭建、地图预处理优化、全覆盖规划算法迭代等关键技术。通过三次算法升级,最终实现92%的清洁效率,并分享DWA调参、状态机设计等实战经验,为开发者提供从仿真到落地的完整解决方案。

weixin_29053695的博客 352

第17条:要么为继承设计,并提供文档说明,要么就禁止继承

首先,该类的文档必须精确地描述覆盖每个方法所带来的影响。换句话说,该类必须有文档说明他可覆盖(overridable)的方法的自用型(self-use)。 对于每个共有的或受保护的方法或构造器,他的文档必须指明该方法或者构造器调用了哪些可覆盖的方法,是以什么顺序调用的,每个调用的结果又是如何影响后续的处理过程的。更一般的,类必须在文档中说明,在哪些情况下会调用可覆盖的方法。(例如:后台的线程或者...

爱.NET 183

模型剪枝实战 | Torch-Pruning 库在YOLOv8上的应用指南

本文详细介绍了如何使用Torch-Pruning库对YOLOv8模型进行结构化剪枝,以实现模型“瘦身”。通过DepGraph(依赖图)技术自动处理层间依赖,确保剪枝安全。文章提供了从环境搭建、核心原理理解到完整剪枝流程的实战指南,并强调了剪枝后的微调与性能评估,帮助开发者在保持精度的同时显著提升模型推理速度。

weixin_29046035的博客 503

喷雾破碎模型解析:从理论到CFD应用实践

本文深入解析喷雾破碎模型的理论基础与CFD应用实践,重点介绍KHRT、TAB和ETAB等主流模型的核心原理与工程调参技巧。通过OpenFOAM实例演示和参数优化建议,帮助工程师精准预测液滴破碎行为,提升燃烧效率与排放控制性能,适用于汽车发动机、燃气轮机等工业场景。

weixin_29281915的博客 499

第十九条:要么为继承而设计并提供文档说明,要么就禁止继承

如果你决定在一个为了继承而设计的类中实现Serializable,并且该类有一个readResolve或者writeReplace方法,就必须使readResolve或者writeReplace成为受保护的方法,而不是私有的方法。如果类是为了继承而被设计的,无论实现这其中的那个接口通常都不是一个好主意,因为他们它一下实质性的负担转嫁到扩展这个类的程序员的身上。当设计一个可能被广泛使用的用于继承的类时,要意识到,我们对写在文档中的方法的自身使用情况,以及隐含在受保护的方法和字段的实现决策做出了永久性的承诺。

weixin_56542271的博客 514

EEGLAB+ERPLAB实战:从.cnt文件到情绪ERP差异波,一份避坑指南

本文详细介绍了使用EEGLAB和ERPLAB处理Neuroscan的.cnt格式脑电数据的全流程,从数据导入、预处理到情绪ERP差异波生成。重点解决了采样率验证、事件标记检查、重参考选择、滤波策略与ICA组合等实操难题,并提供了情绪图片ERP研究中P1、EPN和LPP成分的分析技巧,帮助研究者避免常见错误,提升数据处理效率。

weixin_26795617的博客 264

《Effective Java》第19条:要么设计继承并提供文档说明,要么禁止继承

对于每个公有的或受保护的方法或者构造器,它的文档必须指明该方法或者构造器调用了哪些可覆盖的方法,是以什么顺序调用的,每个调用的结果又是如何影响后续处理过程的(所谓可覆盖的方法,是指非final的、公有的或受保护的)。更广义地说,即类必须在文档中说明,在哪些情况下它会调用可覆盖的方法。,因为父类构造器的执行顺序优先于子类构造器,如果父类构造器调用了可被覆盖的方法,那么就有可能在子类构造器还未执行的情况下,执行了子类的重写方法,如果该重写的方法依赖于子类构造器所执行的任何初始化工作,该方法将不会如预期般执行。

TD_FAlmK的博客 1054

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Effective Java笔记:要么设计继承并提供文档说明,要么禁止继承

这个观点强调的是在使用继承时,设计者必须明确其意图,并为继承行为提供清晰的文档说明来指导子类的扩展。如果无法提供合适的设计和说明,那么禁止继承反而是更好的选择。在很多情况下,复合是一种可以代替继承的更安全的设计模式(见之前“复合优于继承”的讨论)。通过组合其他类而非继承,可以提高类的可维护性和封装性。当一个类的实现很容易因子类滥用而出问题时,应尽可能明确哪些部分是封闭的(不可重写),哪些部分开放给子类(可重写)。对于工具类(跟逻辑无关,只保存一些静态方法),禁止继承是一种推荐的设计方法。

eclipseC的博客 618

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Effective Java 类和接口 第17条:要么为继承而设计,并提供文档说明,要么就禁止继承

第16条提醒我们,对于不是为了继承而设计,并且没有文档说明的“外来”类进行子类化是多么危险。那么对于专门为了继承而设计并具有良好文档说明的类而言,这有意味着什么呢? 该类的文档必须精确的描述覆盖每个方法所带来的影响。(java.util.AbstractCollection) /** * Removes a single instance of the specified el...

yancyang的博客 1万+

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

《Effective Java》阅读笔记 17要么为继承而设计,并提供文档,要么就禁止继承

面向对象编程,从一开始被洗脑难免在上手写代码时都会首先思考有没有公共方法啊,能不能把两个类抽象成一个父类再继承啊等,慎重使用继承,当要使用继承时一定要在文档注释中写明重写这个方法会给其他方法带来什么影响。书中给出建议如果类并不是为了继承而生,那么这个类应该用final修饰禁止子类化。 1.继承的缺陷 对于为了继承而设计的类,唯一的测试方法就是编写子类。 为了继承,类还必须遵守其他一些约束。构造器绝不能调用可被覆盖的方法,无论是直接调用还是间接调用。 无论是clone还是readObject,都不可以调用可

weixin_41563161的博客 271

Effective Java 要么为继承设计,并提供文档说明,要么就禁止继承

首先,该类的文档必须精确地描述覆盖每个方法所带来的影响。换句话说,该类必须有文档说明他可覆盖(overridable)的方法的自用型(self-use)。 对于每个共有的或受保护的方法或构造器,他的文档必须指明该方法或者构造器调用了哪些可覆盖的方法,是以什么顺序调用的,每个调用的结果又是如何影响后续的处理过程的。更一般的,类必须在文档中说明,在哪些情况下会调用可覆盖的方法。(例如:后台的线程或者静态的初始化可能会调用这个方法) 按惯例,如果方法调用了可覆盖的方法,在他的文档注释的末尾应该包含关于这些调用的描

菜园子丶For丨丶Tomorrow的博客 147

Effective Java笔记第三章类和接口第五节要么为继承而设计,并提供文档说明,要么就禁止继承

Effective Java笔记第三章类和接口 第五节要么为继承而设计,并提供文档说明,要么就禁止继承 1.对于专门为了继承而设计并具有良好文档说明的类而言,首先,该类的文档必须精确地描述覆盖每个方法所带来的影响。换句话说,该类必须有文档说明它可覆盖的方法的自用性。对于每个公有的或受保护的方法或者构造器,他的文档必须指明该方法或者构造器调用了哪些可覆盖的方法,是以什么顺序调用的,每个调用的结果又是如何影响后续的处理过程的(所谓可覆盖的方法,是指非final的,公有的或受保护的)。更一般地,类必须在文档中说明

zh123456_789的博客 216

要么设计继承并提供文档说明,要么禁止继承——《effective Java》 第三版

为了继承而进行的设计不仅仅涉及自用模式的文档设计。为了使程序员能够编写出更加有效的子类,而无须承受不必要的痛苦,类必须以精心挑选的受保护的(protected)方法的形式,提供适当的钩子(hook),以便进入其内部工作中。这种形式也可以是罕见的实例,或者受保护的域。例如,以java.util.AbstractList 中的 removeRange 方法为例: protected void removeRange(int fromIndex, int toIndex) (从列...

m0_65546127的博客 681

《Effective Java》解读第19条:要么设计继承并提供文档说明,要么禁止继承

摘要: 继承是强大但危险的机制,除非类专门为继承设计,否则应禁止继承。为继承设计的类需详细文档说明可重写方法的影响,提供protected方法供安全重写,并避免在构造器、clone和readObject中调用可重写方法。禁止继承的两种方式:声明类为final,或将构造器设为private/package-private并通过静态工厂提供实例。由于为继承设计需要大量工作且限制多,大多数普通类应禁止继承以保证安全。(149字)

Cosmoshhhyyy的博客 250

跟我学(Effective Java 2)第17条:要么为继承而设计,并提供文档说明,要么就禁止继承

第17条:要么为继承而设计,并提供文档说明,要么就禁止继承 首先,该类的文档必须精确地描述覆盖每个方法所带来的影响。换句话说,该类必须有文档说明他可覆盖(overridable)的方法的自用型(self-use)。对于每个共有的或受保护的方法或构造器,他的文档必须指明该方法或者构造器调用了哪些可覆盖的方法,是以什么顺序调用的,每个调用的结果又是如何影响后续的处理过程的。更一般的,类必须在文档中说明...

Dullon_jiang的博客 277

Effective Java 第17条:要么为了继承而设计,并提供文档说明,要么禁止继承

其实在 16 条中说过继承的缺点:  可能会导致子类很脆弱,如果超类用了自用模式并且没有提供相关的文档说明。  后期版本更新中,有可能导致子类实现的方法和超类中同名,从而成为覆盖父类方法。 所以设计超类的时候需要注意这些实质性的规则: 首先,该类的文档必须精确地描述覆盖每个方法所带来的影响。该类必须有文档说明其可改写的方法的自用性:对于每一个公有的或

Come on ! Just Do it ! 2967

Effective Java 学习笔记--第18、19条继承与复合

介绍继承与复合的设计以及两者的优劣分析

weixin_50353846的博客 1088

《Effective java》读书记录-第17条-要么为继承而设计,并提供文档说明,要么就禁止继承

可继承类必须有文档说明它可覆盖(overridable)的方法的自用性(self-use)。 好的API文档应该描述一个给定的方法做了什么工作,而不是描述它是如何做到的。 类必须通过某种形式提供适当的钩子(hook),以便能够进入到它的内部工作流程中,这种形式可以是精心选择的受保护(protected)方法,也可以受保护的域(比较少见)。 对于为了继承而设计的类,唯一的测试方法就是编写子类。

sunyx1130的专栏 693

effective java(17) 之要么为继承而设计,并提供文档说明,要么就禁止继承

effective java 之要么为继承而设计,并提供文档说明,要么就禁止继承 1、 对于专门为了继承而设计并且具有良好文档说明的类而言,该类的文档必须精确地描述覆盖每个方法所带来的影响。 该类必须有文档说明它可覆盖的方法的自用性。 对于每个公有的或受保护的方法或者构造器,它的文档必须指明该方法或者构造器调用了哪些可覆盖的方法,是以什么顺序调用的,每个调用的结果又是如何影响后续

Eric的博客 447
上一篇: Effective Java笔记(18)复合优先于继承
下一篇: Effective Java笔记(20)接口优于抽象类
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值