今天聊聊kotlin中关于构造函数的一个话题。

我们知道,在kotlin中构造函数分为主构造函数和从构造函数,关于详细的内容,可以点击下面的文章链接了解。
Kotlin系列之主构造方法和初始化语句块
Kotlin系列之从构造方法

前置知识

我们经常会写这样的代码:

//父类
open class Father{}// 子类
class Son: Father(){}

注意到子类在继承父类时,Father 后面的 () 了吗,这里表示父类的主构造函数,而且这个 () 不能少,因为子类的代码完整的写法是下面这样的:

class Son public constructor(): Father(){}

public作为构造函数的权限修饰符这个自然不用多说,后面紧跟的 constructor() 表示 Son 这个类的主构造函数。
所以上面的代码连起来可以理解为子类 Son 的主构造函数需要调用父类 Father 的主构造函数。这样你就知道了Father后面的括号是不能少的。
其实Java里面也是这样的规则,只是Java里面不分主构造函数和次构造函数。

现象

下面我们看一个现象:

// 父类
open class Father{}// 子类
class Son: Father{constructor(){}
}

你会发现,这时候子类继承了 Father,但是Father后面的 () 没有了。
与此同时,Son类中多了一个次构造函数。也就是说,在继承自某个类时,有时候父类后面的 () 是不写的,而且写了会报错。

揭开谜底

如果你Java基础扎实,应该可以猜出几分原因,下面就来解释一下上面这种现象。
首先,我们明确一点,在kotlin中,在声明类的同时书写的构造函数,被我们称为主构造函数,写在类内部的构造函数被我们称为次构造函数。
就像最开始演示的那样,我们经常会把下面的代码简写:

// 完整形式
class Son public constructor(): Father(){}// 简写形式
class Son: Father(){}

简写的形式,没有写出主构造函数的声明,所以kotlin就像Java一样,会在编译时帮我们补一个无参的主构造函数上去。
但是,一旦我们在类内部声明了一个无参的次构造函数,就像下面这样:

class Son: Father{constructor(){}
}

这样kotlin就不会再为我们补无参的主构造函数上去了,这时候Son这个类,就没有了主构造函数。
在原来我们这么做之前,语义是子类的主构造函数,需要调用父类的主构造函数,所以我们需要在Father后面加上括号,
现在子类没有主构造函数了,自然就不需要在声明时调用父类的主构造函数了,Father后面就不需要写括号了,只需要写Father来表明这是一种继承关系即可。

这就引出了另一个问题,这样写,那是不是子类的次构造函数就没法调用父类的主构造函数了。在Java里面子类的构造函数时一定要调用父类的构造函数的。难道在kotlin中不一样吗?

我们可以通过命令反编译生成的Son.class文件一探究竟。先切换到Son.class所在目录,并使用如下命令进行反编译:

cd out/production/Sample/
javap -c Son

反编译结果如下:

Compiled from "Son.kt"
public final class Son extends Father {public Son();Code:0: aload_01: invokespecial #8                  // Method Father."<init>":()V4: return
}

你可以很清楚地看到,最终还是会在编译时帮我们补上调用父类构造函数的代码的。

写在最后

其实kotlin跟Java有很多相似的地方,理解了Java,kotlin可以看作是Java的高级语法糖,但万变不离其宗。

kotlin小悟-这个继承有点不一样相关推荐

  1. “智能语音助手”的竞品分析 —— 你好小悟小爱同学(3)

    关于用户画像 数据来源(艾瑞咨询:<2018年中国智能语音助手企业案例研究报告>) 用户数据: 居住于一.二线城市,占比76.4%: 男性,占比61.7%: 年龄层次26-35岁之间,占比 ...

  2. “智能语音助手”的竞品分析 —— 你好小悟小爱同学(2)

    关于难点 技术: ASR: 对于ASR来说"远场"."纠错"."全双工"是3大难点: 在"远场"上,是智能音箱们需要优化 ...

  3. Java继承之object类、继承小练习和继承简单工厂模式

    1.object类常见方法 (1)Java中,所有类都直接或间接继承自java.lang.Object类,Object类可以说是Java中所有类的祖先即根类 (2)Java中任何类都继承了Object ...

  4. Kotlin小知识之高阶函数

    文章目录 高阶函数 定义高阶函数 函数类型 高阶函数示例 内联函数 内联函数的作用 内联函数的用法 noinline与crossinline 高阶函数 定义高阶函数 高阶函数和Lambda的关系是密不 ...

  5. 恍然小悟,去掉Excel的worksheet(工作表)保护的新方法

    2019独角兽企业重金招聘Python工程师标准>>> 广为认知的方法是,运行一段猜测密码的VBA(https://uknowit.uwgb.edu/page.php?id=2885 ...

  6. 知识点小悟2019-1-18

    canvas 绘图有关 1.旋转,平移,缩放三种变换 一个三维的矩阵可以表示二维坐标的这三种变换 一个四维的矩阵可以表示三维坐标的这三种变换 2. this.drift = function(dx, ...

  7. linux用户切换pts,Linux下的tty,pts,pty…和多窗口切换 | 云上小悟

    Linux下TTY(TeleType)的概念就是控制台终端的意思,TTY最初就是指那种老式的打字机. 如果你在vmware中安装ubuntu之后,你会发现有6个tty控制台可以用,通过Ctrl+Alt ...

  8. 都掌握了吗?Kotlin技能小成

    前些文章描述了 Kotlin教程,包括一些基本语法. 很多时候,还需要加以练习. 本文将开发过程中,遇到的点,整理成线,继而到面 希望 把下面的问题掌握之后,掌握Kotlin在Android中的开发能 ...

  9. Kotlin学习笔记 第二章 类与对象 第一节类与继承(补)

    参考链接 Kotlin官方文档 Kotlin docs | Kotlin 本系列为参考Kotlin中文文档 kotlin官方文档2020版.pdf-其它文档类资源-CSDN下载 第二章 第一节 类与继 ...

最新文章

  1. webmin远程命令执行漏洞(cve-2019-15107)深入分析
  2. python 机器学习_使用Python启动机器学习
  3. Java校招面试经验汇总,最终入职阿里
  4. telnet命令发送邮件
  5. 两块网卡实现多台机器共享上网
  6. TypeError: can't pickle _thread.RLock objects
  7. jquery datatables 学习笔记
  8. github的应用详解
  9. Android RecyclerView (十)组件化封装
  10. MyBatis学习(十)--MyBatis数据操作
  11. 软件集成策略故事连载----构建错误是怎么来的
  12. vs2015连接oracle(11g)的方法
  13. 《PMP学习笔记》11.7 子过程:实施风险应对
  14. windows10如何截长图
  15. 传递组播与广播帧:数据待传指示传递信息(DTIM)
  16. Excel2003和Excel2007对下拉选择和下拉级联选择的操作以及java程序的调用
  17. declare 简单用法
  18. 永恒之蓝漏洞复现-CVE-2017-0144
  19. Revit二次开发之技能篇(一)———轴网自动对齐
  20. [OpenCV实战]10 使用Hu矩进行形状匹配

热门文章

  1. can t find dynamically referenced class android os systemproperties
  2. 【版本管理】版本管理规范
  3. js实现一个时分秒计时器
  4. 安卓手机被抓包了怎么办?如何防止?
  5. 2020年数字设计/芯片前端面试经验-格科微+盛科科技+瑞晟+长江存储+兆芯
  6. 《CDN 之我见》系列三:详解篇(网络优化)
  7. 潮信服务器端保不保留客户信息,潮信app(潮信无痕聊天)V2.9.6 手机版
  8. 无法用 CString 类型的值初始化 CWnd 类型的引用(非常量限定)
  9. 微软亚研副院长周明离职,将出任创新工场AI工程院首席科学家
  10. 无货源模式,跨境电商时代的风向标