当前位置:网站首页>Kotlin属性与字段
Kotlin属性与字段
2022-07-26 08:37:00 【尘心平】
目录
属性的声明
在主构造函数中声明
在主构造函数中采用 var/val 变量:类型 即可声明属性
open class A(var name:String,var node:String){ override fun toString(): String { return "A(name='$name', node='$node')" //name,node即属性 } } fun main(args:Array<String>){ var a=A("Hellen","1") println(a) //A(name='Hellen', node='1') }
在属性初始化器中声明
具体格式为:
var/val 属性名 [ : 属性类型 ] [ =值 ]
[ 访问权限符 set()=/set(){} ]
[ 访问权限符 get()=/get(){} ]
其中 [ ] 内为可选部分,var变量有get和set方法,而val变量只有get方法
当属性类型可以由set和get推断出时,属性类型可省略,但val只有get方法,必须声明类型
一般指定值,就可省略属性类型
var count=1 open class A{ var name:String //有了默认get,自定义了set和构造函数,值省略 private set(value){ field=value println("set name's value") } val node:Int get() { return count++ }//只有get默认,值不能省略。可指定值,省去类型 constructor(name:String){ this.name=name } override fun toString(): String { return "A(name='$name', node=$node)" } } fun main(args:Array<String>){ var a=A("Hellen") //set name's value var b=A("Peter") //set name's value var c=A("John") //set name's value println(a) //A(name='Hellen', node=1) println(b) //A(name='Peter', node=2) println(c) //A(name='John', node=3) }
属性的使用
一般属性在类中可直接用属性名访问,有名称冲突时可以使用this.属性名;在类外可以通过 对象.属性名 访问public属性
var count=1 open class A{ var name:String set(value) { field=value println("name's set") } val node get() = count++ var kotlin_score:Int val kotlin_level:String get() { println("kotlin_level's get") return when(kotlin_score/10){ 9,10->{ "A" } 8->{ "B" } 6,7->{ "C" } else->{ "D" } } } constructor(name:String,kotlin_score:Int){ this.name=name //名称冲突,用this.属性名访问 this.kotlin_score=kotlin_score //名称冲突,用this.属性名访问 //this.属性名=变量/值,默认调用属性名的set函数 } override fun toString(): String { //无名称冲突,直接用属性名访问 return "A(name='$name', node=$node, kotlin_score=$kotlin_score, kotlin_level='$kotlin_level')" //$属性名,会默认调用属性名的get函数 print(属性名)等需要属性名值的地方都是默认调用了属性名的get函数 } } fun main(args:Array<String>){ var a=A("Hellen",85) //name's set var b=A("Peter",100) //name's set var c=A("John",67) //name's set println(a) //kotlin_level's get //A(name='Hellen', node=1, kotlin_score=85, kotlin_level='B') println(b) //kotlin_level's get //A(name='Peter', node=2, kotlin_score=100, kotlin_level='A') println(c) //kotlin_level's get //A(name='John', node=3, kotlin_score=67, kotlin_level='C') println(c.name+" "+c.kotlin_score)// 类外可调用对象的public属性,对象.属性名 }
幕后字段
幕后字段主要是解决属性的set函数调用赋值时的内存溢出问题,主要用于让一个属性在不同的条件下有不同的值
一般按照Java的理解,set函数会写成如下这样的形式
var name:String set(value) { this.name=value }
这样写IDEA会报黄,显示未分配setter
这样运行以后也会出现报错:栈溢出StackOverflowError
将Kotlin类转换为Java如下,可见有setName循环调用
public class A { @NotNull private String name; @NotNull public final String getName() { return this.name; } public final void setName(@NotNull String value) { Intrinsics.checkNotNullParameter(value, "value"); this.setName(value);//循环调用 } @NotNull public String toString() { return "A(name='" + this.name + "')"; } public A(@NotNull String name) { Intrinsics.checkNotNullParameter(name, "name"); super(); this.setName(name); } }
因此为了解决这个问题,就引出了幕后字段:在Kotlin中, 如果属性至少一个访问器使用默认实现,那么Kotlin会自动提供幕后字段。幕后字段用关键字field表示,指代当前的属性,只能用于get和set函数中,也因此,set函数写作如下:
var name:String set(value) { field=value //field指代属性name }
注意:并不是所有的Kotlin属性都有幕后字段:要满足以下两种情况之一:set和get其中之一采用默认实现;自定义的set和get中使用field
幕后属性
幕后属性满足:对类外只可读,但在类内既可读又可写
实现幕后属性需要两个变量的声明:
(官方这样要求,但应该可以通过声明var属性但是自定义 public get,private set 实现幕后属性的特点,只是反编译的Java代码不同)
private var a: Int=0 public val m_a: Int get() = a //a即为幕后属性 //反编译为: //public class A { // private int a; // // public final int getM_a() { // return this.a; // } //}
var a:Int=0 private set(value){ field=value }//get默认public //反编译为 //public class A { // private int a; // // public final int getA() { // return this.a; // } // // private final void setA(int value) { // this.a = value; // } //} // 较官方使用,多反编译了set函数
边栏推荐
- Oracle 19C OCP 1z0-083 question bank (1-6)
- Special lecture 2 dynamic planning learning experience (should be updated for a long time)
- Lesson 3: gcc compiler
- Problems caused by slivereappbar
- Neo eco technology monthly | help developers play smart contracts
- 有限元学习知识点备案
- Kotlin中room数据库的使用
- shell编程
- Mysql8 one master one slave +mycat2 read write separation
- A summary of practical websites that won't brighten people's eyes
猜你喜欢
随机推荐
Excel delete blank lines
Flutter text is left aligned with no blank space in the middle
Super nice navigation page (static page)
23.5 event listeners of application events and listeners
Kotlin program control
各位老师,请问在flinkcdc中,sqlserver如何获取到ddl?
基于C语言设计的换乘指南打印系统
import error: ‘Icon‘ is not exported from ‘antd‘. Import icon error
Two ways to monitor the change of user points
2022-7-5 personal qualifying 2 competition experience
flink oracle cdc 读取数据一直为null,有大佬知道么
Oracle 19C OCP 1z0-082 certification examination question bank (42-50)
CV learning notes (optical flow)
Oracle 19C OCP 1z0-083 question bank (7-12)
【FreeSwitch开发实践】使用SIP客户端Yate连接FreeSwitch进行VoIP通话
After MySQL 8 OCP (1z0-908), hand in your homework
2022年全国职业院校技能大赛“网络安全”竞赛试题文件上传渗透测试答案Flag
Oracle 19C OCP certification examination software list
Uninstallation of dual systems
有限元学习知识点备案