谈谈 Kotlin 中的构造方法,有哪些注意事项?

在 Kotlin 中,构造方法分为主构造方法(Primary Constructor)和次构造方法(Secondary Constructor)。

1 主构造方法

主构造方法是类的核心构造方法,直接在类头声明,位于类名之后。

1.1 基本语法
class Person constructor(val name: String, val age: Int) {// 类体
}

如果主构造方法没有注解或可见性修饰符,constructor 关键字可以省略:

class Person(val name: String, val age: Int) {// 类体
}
1.2 特点
1.2.1 属性声明

参数直接作为属性:可通过 valvar 将主构造函数的参数声明为类的属性。

class Person(val name: String, age: Int) {// name 是属性,age 是构造方法参数
}
1.2.2 构造方法参数的作用域

主构造方法的参数可以在类体中直接使用,但未声明 val/ var 的参数仅在 init 代码块和属性初始化器中可见。

class User(private val id: String, name: String, age: Int) {// id 是类属性,在任何地方都可以用// name、age 仅在 init 代码块和属性初始化器中可见val displayName = "[$id] $name"init {println("age = $age")}
}

属性初始化器是用于在声明属性时直接赋值的语法,它允许在类体或主构造函数中直接为属性设置初始值。

属性初始化器可以在以下两种场景中使用:

  • 主构造函数中声明属性并初始化;
  • 类体中可以直接初始化属性;
// 通过主构造函数参数声明属性并初始化
class User(val name: String = "Unknown", var age: Int = 0)class User {val name: String = "Unknown" // 属性初始化器val age: Int = 0 // 属性初始化器
}
1.2.3 初始化代码

使用 init 代码块执行额外的初始化逻辑。

class User(name: String, age: Int) {val formattedName: Stringinit {formattedName = "Mr./Ms. $name"println("Person initialized: $formattedName")}
}
1.2.4 可见性修饰符

主构造函数的可见性默认是 public,可显式指定:

class User private constructor(val name: String) // 私有构造方法

2 次构造方法(Secondary Constructor)

次构造方法通过 constructor 关键字在类体内定义,必须直接或间接调用主构造函数。

2.1 基本语法
class Person(val name: String) {var age: Int = 0// 次构造方法必须直接或间接委托给主构造方法constructor(name: String, age: Int) : this(name) {this.age = age}
}
2.2 注意事项
2.2.1 必须委托

每个次构造函数必须通过 this() 调用主构造函数或其他次构造函数,确保所有初始化路径都经过主构造函数:

class User {constructor(name: String) : this(name, 0) // 错误:没有主构造方法constructor(name: String, age: Int) // 如果没有主构造方法,次构造方法无需委托
}
2.2.2 初始化顺序

主构造函数的参数初始化 —> init 代码块 —> 次构造函数体:

class User(val name: String) {init {println("主构造方法初始化")}constructor(name: String, age: Int) : this(name) {println("次构造方法执行")}
}fun main() {User("Eileen", 34)
}// 主构造方法初始化
// 次构造方法执行
2.2.3 避免与主构造方法参数冲突

次构造方法的参数名应避免与主构造方法的属性名重复:

class User(val name: String) {constructor(name: String, age: Int) : this(name) {// 此处的 name 参数会屏蔽类的 name 属性}
}

3 初始化顺序

  • 主构造函数参数初始化;
  • 类属性按声明顺序初始化;
  • init 块按出现顺序执行;
  • 次构造函数执行;
class User(val name: String = "Eileen") {val a = println("a 初始化")init {println("init 1")}val b = println("b 初始化")init {println("init 2")}
}fun main() {User()
}// a 初始化 -> init 1 -> b 初始化 -> init 2

4 默认参数替代次构造方法

Kotlin 支持构造函数参数默认值,可减少构造函数的数量:

class User(val name: String,val age: Int = 0, // 默认参数val country: String = "Unknown"
)fun main() {val user1 = User("Eileen")val user2 = User("Eileen", 34)val user3 = User("Eileen", 34, "China")
}

Java 互操作性:如果需要在 Java 中调用带默认参数的构造方法,需添加 @JvmOverloads 注解:

class Person @JvmOverloads constructor(val name: String,val age: Int = 0,val country: String = "Unknown"
)

5 继承中的构造方法

5.1 子类必须初始化父类构造方法

子类的主构造方法需初始化父类的主构造方法:

open class User(val name: String)class Student(name: String) : User(name)

如果父类只有次构造方法(无主类构造方法),子类需通过 super 调用父类的某个次构造方法:

open class User {constructor(name: String) {}
}class Student : User {constructor(name: String) : super(name)
}
5.2 抽象类的构造方法

抽象类的构造函数可由子类实现:

abstract class User(val name: String)class Student(name: String, val age: Int) : User(name)

6 数据类中的构造方法

数据类的主构造方法必须至少有一个参数,且所有的参数必须标记为 valvar

数据类的主构造方法

7 总结

场景注意事项
主构造方法参数可声明为属性,初始化顺序严格,支持默认参数替代次构造方法
次构造方法必须委托主构造方法,代码体在类初始化后执行
继承子类必须初始化父类构造方法,优先使用主构造方法
默认参数替代次构造方法,需要 @JvmOverloads 支持 Java 调用
初始化顺序init 块和属性初始化按照代码顺序执行,次构造方法体最后执行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/81926.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

年会招标抽奖活动软件———仙盟创梦IDE

年会是企业一年的总结与欢庆时刻,而抽奖环节更是点燃全场气氛的关键。如何让抽奖环节既大气又充满仪式感?选对抽奖软件至关重要!本文精心挑选了 3 款兼具实用性与氛围感的年会抽奖软件,从界面设计到功能特色,全方位为你…

安全软件检测进程异常行为-Postgresql应用执行异常指令whoami

文章目录 环境症状问题原因解决方案 环境 系统平台:UOS(海光) 版本:4.5.8 症状 数据库安装包: 安全软件告警中提示“sh -c whoami”命令,是由数据库发出的,安全软件捕获到了postgres.exe–fo…

车载诊断架构 --- LIN 节点 ECU 故障设计原则

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…

GPU加速的AlphaFold3蛋白质复合体预测:如何在64GB显存下跑超大规模模型(混合精度+模型并行实战技巧)

一、AlphaFold3的超大规模挑战与优化方向 AlphaFold3作为当前生物计算领域的革命性工具,其核心架构基于扩散模型,能够预测包含蛋白质、核酸、小分子配体等复杂生物复合物的三维结构。然而,模型参数量级(典型配置超百亿级&#xf…

Qt功能区:Ribbon控件

控件 1. 按钮1.1 多选按钮1.2 2. 下拉列表框SARibbonComboBox2.1 简介2.2 代码实现 1. 按钮 1.1 多选按钮 软件功能:用于实现Category的名称居中。 SARibbonCheckBox继承于QCheckBox,使用方法完全相同。 SARibbonCheckBox* checkBox new SARibbonChe…

一个由微软开源的 Python 工具,用于将多种文件格式转换为 Markdown 格式

📚 Markitdown 由微软开源的 Python 工具,用于将多种文件格式转换为 Markdown 格式 支持:PDF、PowerPoint、Word、Excel、图像、音频、HTML、文本格式(CSV、JSON、XML)、ZIP 文件的转换。 它旨在提供一个简单且灵活的…

Linux的进程概念

目录 1、冯诺依曼体系结构 2、操作系统(Operating System) 2.1 基本概念 2.2 目的 3、Linux的进程 3.1 基本概念 3.1.1 PCB 3.1.2 struct task_struct 3.1.3 进程的定义 3.2 基本操作 3.2.1 查看进程 3.2.2 初识fork 3.3 进程状态 3.3.1 操作系统的进程状态 3.3…

export和import的书写方式

一、导出模块(export) 1. 命名导出(Named Exports) // math.js export const PI 3.14159; // 导出单个常量 export function sum(a, b) { return a b; } // 导出单个函数 export class Calculator { /* ..…

HOW - 结合 AI 进行 Tailwind 样式开发

文章目录 情况 1:使用 Tailwind CSS 与手写传统 CSS 的开发效率对比情况 2:AI Tailwind 自动生成 UI 的效率如何?总结 在 WHAT - Tailwind 样式方案(不写任何自定义样式) 中我们已经简单介绍过 Tailwind。今天主要认识…

java面试每日一背 day1

1.什么是缓存穿透 缓存穿透是指查询一个数据库中根本不存在的数据,导致这个查询请求绕过缓存直接访问数据库的情况。这种情况如果频繁发生,会对数据库造成不必要的压力。 典型特征: (1)查询的数据在数据库和缓存中都…

ngx_http_realip_module 模块概述

一、使用场景 日志记录 记录真实客户端 IP 而非反向代理的 IP,有助于流量分析和安全审计。访问控制 基于真实 IP 实现防火墙规则(allow/deny)或限流,而非误将上游 IP 视为客户端。GeoIP、WAF、限速等功能 模块化的上游真实 IP 支…

实战5:个性化数字艺术生成与销售

盈利思路 数字艺术销售: 平台销售:将生成的数字艺术作品上传到像OpenSea、Foundation等NFT平台进行售卖。每一件独特的艺术品可以通过NFT技术保证其唯一性,吸引收藏家和投资者。 定价策略:根据作品的复杂度、创意性以及市场需求来…

游戏引擎学习第303天:尝试分开对Y轴和Z轴进行排序

成为我们自己的代码精灵α 所以现在应该可以正常使用了。不过,这两周我们没办法继续处理代码里的问题,而之前留在代码里的那个问题依然存在,没有人神奇地帮我们修复,这让人挺无奈的。其实我们都希望有个神奇的“代码仙子”&#…

InetAddress 类详解

InetAddress 类详解 一、核心作用 封装 IP 地址:同时支持 IPv4 和 IPv6 地址域名解析:将域名转换为 IP 地址(DNS 查询)地址验证:检查网络地址的有效性无构造方法:通过静态工厂方法获取实例 二、核心方法 …

spring cloud alibaba-Geteway详解

spring cloud alibaba-Gateway详解 Gateway介绍 在 Spring Cloud Alibaba 生态系统中,Gateway 是一个非常重要的组件,用于构建微服务架构中的网关服务。它基于 Spring Cloud Gateway 进行扩展和优化,提供了更强大的功能和更好的性能。 Gat…

iOS 直播技术及优化

iOS直播技术的实现和优化涉及多个技术环节,需结合协议选择、编解码方案、播放器技术及性能调优等多方面。 一、核心技术实现 协议选择与传输优化 HLS(HTTP Live Streaming):苹果官方推荐,基于HTTP分片传输&#xff0c…

目标检测135个前沿算法模型汇总(附源码)!

目标检测是计算机视觉核心方向之一,也是发论文的热门领域! 近来不仅YOLO算法迎来了新突破,迭代出YOLOv12!Mamba、大模型等新技术的发展,也给该领域注入了全新的力量,取得了诸多显著成果。比如性能飙升82.3…

期刊采编系统安装升级错误

我们以ojs系统为例: PHP Fatal error: Uncaught Error: Call to a member function getId() on null in /esci/data/html/classes/install/Upgrade.inc.php:1019 Stacktrace: #0 /esci/data/html/lib/pkp/classes/install/Installer.inc.php(415): Upgrade->con…

浅谈无服务器WebSocket的优势

实际上,一个实用的解决方案是将构建业务关键型实时平台的复杂性卸载到专门的云服务中。 完全托管的无服务器 WebSocket 解决方案为事件驱动的消息传递提供了基础结构;它使底层基础设施成为一种商品。客户端使用提供程序服务发送/接收低延迟消息,并专注于…

Python数据可视化高级实战之二——热力图绘制探究

目录 一、热力图的作用 二、热力图反映的信息类型 三、热力图的典型应用场景 1. 地球信息系统 (GIS) 2. 城市交通分析 3. 市场分析 4. 用户行为分析 5. 网络流量分析 6. 传染病传播分析 7. 社交媒体舆情分析 四、Python 绘制热力图的关键技术要点 1. 数据预处理 2. 颜色选择与渐…