做微商建自己的网站有用吗,睢宁建网站,自己做名片的网站,WordPress自己写主题在前面一条中#xff0c;我们已经知道了David写了A类被Tom拿去继承了#xff0c;导致了A类的封装性遭到了破坏#xff0c;那么有没有可能做点事情避免此事发生呢#xff1f;第十九条孕育而生#xff01;David在创建A类的时候写上文档说明#xff0c;说Al类不允许任何类来…在前面一条中我们已经知道了David写了A类被Tom拿去继承了导致了A类的封装性遭到了破坏那么有没有可能做点事情避免此事发生呢第十九条孕育而生David在创建A类的时候写上文档说明说Al类不允许任何类来继承Tom看到后就不会这么做了除非Tom喜欢写狮山代码一上来不看别人别的文档说明一上来就操作猛如虎这类人现实中其实挺多的。 好的API应该描述一个给定的方法做了什么工作而不是描述他是如何做到的。 那么当你为了继承而设计的类的时候如何决定应该暴露那些受保护的成员呢遗憾的是并没有神奇的法则可供你使用。唯一的方法就是测试。 要测试一个为继承而设计的类唯一的测试方法就是编写子类。经验表明3个子类通常就足可以测试一个可扩展的类。 当设计一个可能被广泛使用的用于继承的类时要意识到我们对写在文档中的方法的自身使用情况以及隐含在受保护的方法和字段的实现决策做出了永久性的承诺。这些承诺可能会使在随后的版本中改进这个类的性能或功能变得困难甚至不可能。因此在发布之前必须通过编写子类来测试。 还有些允许继承的类必须遵守的限制。构造器不得直接或者间接调用可重写的方法。违反这个规定有可能导致程序失败。超类的构造器会在子类的构造器之前运行所以子类重写的方法会在子类构造器之前被调用。 例子
public class Super{//存在问题 构造器调用了一个可重写的方法public Super() {overrideMe();}public void overrideMe(){}
}
public final class Sub extends Super{// 一个空的final字段由构造器设置private final Date date;public Sub(){datenew Date();}//超类构造器调用的重写方法Overridepublic void overrideMe(){System.out.println(date);}public static void main(String[] args){Sub subnew Sub();sub.overrideMe();}
}
结果
Connected to the target VM, address: 127.0.0.1:51415, transport: socket
null
Wed Jun 26 21:52:51 CST 2024
Disconnected from the target VM, address: 127.0.0.1:51415, transport: socketProcess finished with exit code 0
你可能会期待这个程序会打印出日期俩次但是它第一次打印出的是null因为overrideMe方法被Super构造器调用的时候构造器Sub还没有机会初始化Date域。 在为了继承而设计的类的时候Cloneable和Serializable接口出现了特殊的困难。如果类是为了继承而被设计的无论实现这其中的那个接口通常都不是一个好主意因为他们它一下实质性的负担转嫁到扩展这个类的程序员的身上。 如果你决定在一个为了继承而设计的类中实现Cloneable或者Serializable接口就应该意识到因为clone和readObject方法在行为上非常类似于构造器所以类似的限制规则也是使用的无论是clone还是readObject都不可以调用可覆盖的方法不管是以直接还是间接的方式。 如果你决定在一个为了继承而设计的类中实现Serializable并且该类有一个readResolve或者writeReplace方法就必须使readResolve或者writeReplace成为受保护的方法而不是私有的方法。 现在我们很清楚了设计一个用于继承的类需要付出巨大的努力对类本身也是很大的限制。 解决这个问题的最佳方案是对于并非为可以安全地子类化而设计并提供文档说明的类禁止对其子类化。 所有文章无条件开放顺手点个赞不为过吧