新建类
空类
class Grad{
}
//对象使用
fun main(args:Array<String>) {
val g = Grad()
}
类的属性
类的属性默认为 public
var:默认实现get set方法
val:默认实现get 方法
get 和 set 方法不建议手动写
class Grad {
var i: Int = 0
// get() = field
// set(value) {
// field = value
// }
var j: String = ""
// get() = field
// set(value) {
// field = value
// }
//初始化代码块
init {
this.i = 1
this.j = "hello world"
}
}
//对象使用
fun main(args:Array<String>) {
val g = Grad()
println(g.i)
println(g.j)
}
//输出
1
hello world
关于field字段:
这个问题对 Java 开发者来说十分难以理解,网上有很多人讨论这个问题,但大多数都是互相抄,说不出个所以然来,要说还是老外对这个问题的理解比较透彻,可以参考这个帖子:https://stackoverflow.com/questions/43220140/whats-kotlin-backing-field-for/43220314
其中最关键的一句:Remember in kotlin whenever you write foo.bar = value it will be translated into a setter call instead of a PUTFIELD.
也就是说,在 Kotlin 中,任何时候当你写出“一个变量后边加等于号”这种形式的时候,比如我们定义 var no: Int 变量,当你写出 no = … 这种形式的时候,这个等于号都会被编译器翻译成调用 set 方法;而同样,在任何位置引用变量时,只要出现 no 变量的地方都会被编译器翻译成 get 方法。那么问题就来了,当你在 set 方法内部写出 no = … 时,相当于在 setter 方法中调用 setter 方法,形成递归,进而形成死循环来自https://www.runoob.com/kotlin/kotlin-class-object.html
如果声明属性为private,var可以写get 和 set方法,val只能写get方法
class Grad {
var i: Int = 0
var j: String = ""
init {
//类初始化代码
this.i = 1
this.j = "hello world"
}
private var k: String = ""
fun getK(): String{
return k
}
fun setK(k: String){
this.k = k
}
}
//对象使用
fun main(args:Array<String>) {
val g = Grad()
g.setK("CSDN")
println(g.getK())
}
//输出
CSDN
构造方法
用 constructor 注明
分两类:主构造方法和次构造方法。且前者只能有一个,后者可以有多个
如果一个非抽象类没有显式声明构造方法(主构造方法和次构造方法),它会默认生成一个无参主构造方法,默认为 public
主构造方法 在 类头部 声明,写法如下
class 类名 [访问修饰符] [constructor] (参数){
}
如果主构造方法没有访问修饰符(比如private),constructor可以省略
class Grad(s: String){
}
class Grad constructor(){
}
class Grad constructor(s: String){
}
例子
class Grad constructor(s: String){
var k: String = ""
init {
this.k = "hello $s"
}
}
//对象使用
fun main(args:Array<String>) {
val g = Grad("CSDN")
println(g.k)
}
//输出
hello CSDN
次构造方法 在类体,必须使用constructor关键字
class Grad {
private val s: String
constructor(s: String) {
this.s = s
}
}
当类中既有主构造方法又有次构造方法时,次构造方法需要直接或间接代理主构造方法,使用 this 关键字
例子(直接代理)
//主构造方法无参,次构造方法有参,但需要代理主构造方法
class Grad constructor(){
private var s: String = "hello world"
//此时直接代理主构造方法
constructor(s: String) : this() {
this.s = "hello $s"
}
fun getS(): String{
return s
}
}
//对象使用
fun main(args:Array<String>) {
val g1 = Grad()
val g2 = Grad("CSDN")
println(g1.getS())
println(g2.getS())
}
//输出
hello world
hello CSDN
例子(间接代理)
class Grad constructor(){
private var s: String = "hello world"
private var k: Int = 0
constructor(s: String) : this() {
this.s = "hello $s"
}
//此时次级代理另一个次级
constructor(s: String, k: Int) : this(s){
this.k = k
}
fun getS(): String{
return s
}
fun getK(): Int{
return k
}
}
//对象使用
fun main(args:Array<String>) {
val g1 = Grad()
val g2 = Grad("CSDN")
val g3 = Grad("csdn",1)
println(g1.getS()+"|"+g1.getK())
println(g2.getS()+"|"+g2.getK())
println(g3.getS()+"|"+g3.getK())
}
//输出
hello world|0
hello CSDN|0
hello csdn|1
参考:Kotlin 类和对象