【问题标题】:Why are Kotlin classes final by default instead of open?为什么 Kotlin 类默认是 final 而不是 open?
【发布时间】:2019-01-11 18:47:18
【问题描述】:

文档告诉我们关于open注解的以下内容:

类上的 open 注解与 Java 的 final 相反:它 允许其他人从这个类继承。默认情况下,所有类 Kotlin 是final,对应Effective Java, 3rd Edition, 第 19 条:设计和记录继承或禁止继承。

我的课

class Foo //I can't inherit it
open class Bar //I can inherit it

默认保留所有类final的真正动机是什么?性能有什么提升吗?还是只是一种设计模式?为什么默认禁止open

【问题讨论】:

  • 您应该阅读 Effective Java 项目。它描述了为继承设计一个类需要多少工作。 极度痛苦的工作量。记录您对子类的所有要求,以及您要求他们不要做的所有事情。构建至少 3 个单独的子类,以验证您的基类实际上是有用的(哦,您不能自己编写这些类;必须由其他人编写,因为您会作弊)。等等等等等等。
  • 大多数类应该是最终的。扩展它们可能是个坏主意。

标签: java performance inheritance design-patterns kotlin


【解决方案1】:

对我来说有两个原因:

首先,Kotlin 从函数式编程世界中汲取了许多想法,并尽可能频繁地使用不变性来避免所有 known problems with mutation

因此,默认情况下将每个类声明为“final”(至少对我而言)是相似的。

在运行时不能更改或更改类(使用反射之类的东西),这会使 Kotlin 编译器的安全检查无用。

所以如果你想“改变”一个类的默认实现,你必须明确地将它标记为打开。

我想到的第二个想法是继承经常被误用。 一些常见陷阱的例子解释了here

有“Favor composition over inheritance”原则作为更好设计的指导方针。因此,默认情况下将每个类声明为 final 会迫使开发人员至少停下来思考解决问题的替代方法,而不是出于错误的原因使用继承。

但只要没有 kotlin 开发者的官方声明,我只能给出一个固执己见的答案。

【讨论】:

    【解决方案2】:

    Kotlin 设计师只是想确保每个人都遵循良好的做法。

    正如已经记录的那样,设计师遵循Joshua Bloch's Effective Java,其中在类和接口一章中谈到了其中一个原则

    设计和记录继承或禁止它

    它提倡在使用之前明确记录任何继承行为的想法。

    假设我们有,

    class Foo 
    

    我们(即使是此代码的非作者) 确信此 class Foo 对任何扩展都是关闭的,并且没有随机类正在使用它,这也是通过查看它的签名。相比之下,Java 类则不能这样说,除非声明为 final,否则某些悬空子类仍然可以扩展它。

    另一方面,

    open class Foo
    

    仅通过类签名,我们就知道这个类是开放的继承,并且可能有多个类覆盖它的行为。如您所见,此处明确记录了继承

    【讨论】:

    • 如果你是 S.O.L.I.D.人,这似乎是在面对Open for Extension的飞行。我发现期末课程非常令人沮丧,尤其是在图书馆中。如果存在错误或者您想扩展它们,这会使过程变得非常复杂。编写良好的库具有内置的可扩展性,但没有人知道未来会怎样或如何使用库。
    【解决方案3】:

    在默认情况下使类 final 可以在运行时使用更少的内存。

    【讨论】:

      【解决方案4】:

      我能想到的另一个原因是 final 使静态调度优化成为可能,这意味着它不需要进行方法表查找。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-27
        • 2014-09-19
        • 1970-01-01
        • 2015-04-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多