Kotlin伴生对象

你已经知道如何为类创建单例对象(singleton)。不过,在很多情况下,你只需要为某个类维护一个单例,这时候使用类的完整名字会显得冗长。比如,你可能只需要存储一个公共的属性。这种情况下,可以用 Kotlin 的另一个特性 —— companion object(伴生对象)


伴生对象(Companion object)

在一个类内部,可以声明一个用 companion 关键字标记的对象:

class Player(val id: Int) {companion object Properties {/* 默认玩家速度 - 每回合移动 7 格 */val defaultSpeed = 7fun calcMovePenalty(cell: Int): Int {/* 计算移动速度的惩罚 */}}
}/* 输出 7 */
println(Player.Properties.defaultSpeed)

解释:
伴生对象是绑定在外部类上的单例,必须通过外部类访问它。它表明该对象与外部类有紧密联系。比如,可以把所有玩家的默认速度存在 Player 类的伴生对象里。每个 Player 实例都会持有伴生对象的引用,访问时都会得到这个唯一实例。


省略伴生对象名字

我们也可以不给伴生对象命名,这样访问时更加简洁:

class Player(val id: Int) {companion object {val defaultSpeed = 7fun calcMovePenalty(cell: Int): Int {/* 计算移动惩罚 */}}
}/* 输出 7 */
println(Player.defaultSpeed)

解释:
省略名字后,仍然可以通过外部类直接访问伴生对象的成员。如果需要,也可以用默认名字 Companion 访问:

/* 依然输出 7 */
println(Player.Companion.defaultSpeed)

伴生对象与外部类

伴生对象与外部类联系非常紧密。在外部类中,可以直接使用伴生对象的属性和方法:

class Deck {companion object {val size = 10val height = 2fun volume(bottom: Int, height: Int) = bottom * height}val square = size * size             // 100val volume = volume(square, height)  // 200
}

同名属性的遮蔽(Shadowing)

如果外部类中有与伴生对象同名的属性,会“遮蔽”伴生对象的同名属性:

class Deck {companion object {val size = 10}val size = 2val square = size * size // 4,使用的是外部类的 size
}

如果想访问伴生对象的 size,需要明确使用伴生对象的名字:

class Deck {companion object {val size = 10}val size = 2val square = Companion.size * Companion.size // 100
}

伴生对象不能访问外部类实例成员

和嵌套对象类似,伴生对象不能访问外部类的实例属性和方法:

class Deck() {val size = 2object Properties {val defaultSize = size // 错误,无法访问外部类的实例变量}
}

伴生对象的限制

  • 每个类最多只能有一个伴生对象,即使起不同名字也不行:
class BadClass {companion object Properties {}companion object Factory {}
}
// 编译错误:每个类只能有一个伴生对象
  • 可以有一个伴生对象,同时拥有多个嵌套对象:
class Player(val id: Int) {companion object Properties {val defaultSpeed = 7fun calcMovePenalty(cell: Int): Int {// ...}}object Factory {fun create(playerId: Int): Player {return Player(playerId)}}
}println(Player.Properties.defaultSpeed) // 7
println(Player.defaultSpeed)             // 7
println(Player.Factory.create(13).id)   // 13
  • 伴生对象不能定义在另一个单例对象或伴生对象内部,因为这会违反全局访问的原则:
object OuterSingleton {companion object InnerSingleton { // 编译错误,伴生对象不能嵌套在对象中}
}

与其他语言的对比

如果你来自其他语言,可能会觉得伴生对象有点陌生。它类似于 Java 或 C++ 中的 static 成员,static 表示成员属于类本身,而不是实例。比如,Java 中:

class Dog {public static int numOfPaws = 4;public static String createSound() {return "WUF-WUF";}
}/* 输出 WUF-WUF */
System.out.println(Dog.createSound());

Kotlin 没有 static 关键字,推荐用伴生对象来实现类似功能:

class Dog {companion object {val numOfPaws: Int = 4fun createSound(): String = "WUF-WUF"}
}/* 输出 WUF-WUF */
println(Dog.createSound())

总结

  • 伴生对象是和类紧密关联的单例对象。

  • 它是组织类级别数据和方法的好方式。

  • 在外部类中可以直接访问伴生对象的成员,反之则不行。

  • 每个类只能有一个伴生对象。

  • 它是 Kotlin 中实现类静态成员的推荐做法。

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

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

相关文章

4G车载录像机的作用详解:提升行车安全与智能管理的核心技术

1. 引言随着物流运输、公共交通、特种车辆等行业对安全与管理需求的提升,4G车载录像机已成为现代车辆智能化管理的重要组成部分。它不仅具备传统行车记录仪的录像功能,还结合4G无线通信、AI智能分析、GPS定位、云存储等技术,实现远程监控、实…

技术与情感交织的一生 (十)

目录 笑傲江湖 上 恨 嫌隙 挣扎 救难 论道 取巧 联手 入魔 决裂 治伤 聚气 倾心 笑傲江湖 上 恨 身边的许多朋友都是金庸武侠迷,我也是其中之一。有人说,我的技术像 “任我行” ,“吸星大法” 学到最后显得不伦不类&#xf…

架构进阶——解读集团IT管控治理体系总体规划【附全文阅读】

集团IT管控治理体系正步入高质量发展阶段,旨在重塑信息化管理价值,解决集团化管理的核心挑战。首要问题是纵向与横向的协同管控,需明确各层级在集团战略决策中的角色与责任,促进跨部门、跨子公司的高效协同。高管激励机制与人才梯…

亚马逊自养号测评实战指南:从环境搭建到安全提排名

在亚马逊平台上,自养号测评系统的成败差异主要源于技术合规性、操作精细度和风控策略的差异。以下是关键因素的分析:🔒 一、环境隔离与伪装技术底层环境稳定性成功案例:采用独立服务器硬件参数伪装(如唯一MAC地址、IME…

CSS中的transform

在 CSS 中,transform 是用于用于用于对元素进行几何变换的属性,可实现旋转、缩放、平移、倾斜等效果,且不会影响其他元素的布局(不会触发重排)。以下是其核心用法和特性: 1. 基本语法 element {transform: …

MyBatis拦截器插件:实现敏感数据字段加解密

文章目录一、写在前面二、编码实现1、注解2、拦截器插件3、配置插件4、实体类5、测试三、扩展1、优化点一、写在前面 日常开发中,经常有一些敏感数据,直接写入数据库的话,很容易泄露。 本文基于mybatis拦截器插件,实现敏感数据的…

C++_Hello算法_队列

队列(queue)是一种遵循先入先出规则的线性数据结构。顾名思义,队列模拟了排队现象,即新来的人不断加入队列尾部,而位于队列头部的人逐个离开。 如图 5-4 所示,我们将队列头部称为“队首”,尾部…

LeetCode 1.

问题描述 俩数之和: 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。你可以按…

c练习-c基础

#include <stdio.h>int main() {//打印数组中的最大值int arr[10];int max,i;for (i 0; i < 10; i){scanf_s("%d", &arr[i]);}max arr[0];for (i 0; i < 10; i){if(max < arr[i 1]){max arr[i 1];}}printf("数组中最大值&#xff1a;%…

Numpy科学计算(五分钟小白从入门到精通)

2.1 numpy介绍numpy是Python中科学计算的基础包。它是一个Python库&#xff0c;提供多维数组对象、各种派生对象&#xff08;例如掩码数组和矩阵&#xff09;以及用于对数组进行快速操作的各种方法&#xff0c;包括数学、逻辑、形状操作、排序、选择、I/O 、离散傅里叶变换、基…

从零掌握微服务通信安全:mTLS全解析

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 在云原生时代&#xff0c;微服务架构的普及带来了灵活性和可扩展性&#xff0c;但也让服务间通信的安全性成为核心挑战。mTLS&#xff08;Mutual TLS&…

Node.js net.Socket.destroy()深入解析

socket.destroy() 是 Node.js net 模块中用于强制销毁 TCP 套接字的方法&#xff0c;比 socket.end() 更彻底。下面我将从多个方面全面讲解这个方法。 基本用法 const net require(net);const server net.createServer((socket) > {// 强制销毁套接字socket.destroy(); })…

vmware 克隆虚拟机,报错:克隆时出错:指定不存在的设备。然后电脑卡死,只能强制关机再开机。

vmware 克隆虚拟机&#xff0c;报错&#xff1a;克隆时出错:指定不存在的设备。然后电脑卡死&#xff0c;只能强制关机再开机。1、问题描述2、问题原因3、解决方法1、问题描述 vmware 版本&#xff1a;vmware workstation pro 17.6.3 克隆虚拟机时&#xff0c;创建完整克隆&am…

如何使用Python将任意PPT变为“智能模板”(解决 python-pptx 替换元素无法保留格式的问题,阴影、填充等属性保留!)

文章目录 📖 介绍 📖 🏡 演示环境 🏡 📒 深入 OpenXML:格式保留的终极武器 📒 🚀 如何打造你自己的“格式保留”PPT模板? 🧐 为什么格式会丢失? 🖼️ 方案一:图片的“格式移植”大法 🛠️ 实现代码 🔹 原理解析 ✍️ 方案二:文本的“外科手术”大法…

学习python中离线安装pip及下载package的方法

正常而言&#xff0c;Python 3.4及以上版本默认自带pip工具‌&#xff0c;无需额外安装&#xff0c;如果需要单独离线安装pip&#xff0c;可以先使用DeepSeek查看指定操作系统能安装的最高pip版本&#xff0c;然后在参考文献1中现在指定版本的pip离线安装文件&#xff0c;通常为…

liunx运维进阶脚本

一、文件与目录操作1.快速创建目录树mkdir -p project/{src,doc,test/{unit,integration}}创建嵌套目录结构&#xff0c;避免逐层创建。2查找并删除7天前的日志文件find /var/log -name "*.log" -mtime 7 -exec rm -f {} \;结合find和exec实现定时清理。3.批量重命名…

Apache Ignite 中的 SQL 模式(Schema)管理机制

这段内容讲的是 Apache Ignite 中的 SQL 模式&#xff08;Schema&#xff09;管理机制。我们可以从几个方面来理解&#xff1a; 一、什么是 Schema&#xff08;模式&#xff09;&#xff1f; 在 SQL 中&#xff0c;Schema 是数据库对象&#xff08;如表、视图等&#xff09;的…

分布式光伏发电多合一(也称为五合一或者群调群控)终端,从功能、市场前景等等方面介绍

对于当下分布式光伏从业者&#xff0c;多合一终端经常被提及到。而且很多地区也有正常使用&#xff0c;目前来看&#xff0c;使用效果也是比较好的&#xff0c;满足当下的使用要求。并且价格也是可以接受。下面从几个方面简单介绍一下。功能介绍 5G通信功能 设备内置 5G通信模组…

AWE2026启动:加码AI科技,双展区联动开启产业新格局

7月22日&#xff0c;由中国家用电器协会主办的2026年中国家电及消费电子博览会&#xff08;AWE2026&#xff09;启动发布会在上海举行。据「TMT星球」了解&#xff0c;AWE2026将以“AI科技、慧享未来”为主题&#xff0c;首次启用“一展双区”的新模式&#xff0c;于2026年3月1…

Django基础(六)———数据库

前言上篇文章给大家介绍了DTL模板结构这篇文章将讲述Django框架与MySQL数据库的综合使用一、Django配置连接数据库在操作数据库之前&#xff0c;首先先要连接数据库&#xff0c;这里我们以配置MySQL为例来讲解。Diango连接数据库&#xff0c;不需要单独的创建一个连接对象。 只…