Kotlin 初探:普通类和对象

新建类

空类

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 类和对象

发布了13 篇原创文章 · 获赞 2 · 访问量 1109

猜你喜欢

转载自blog.csdn.net/AneTist/article/details/103629325