kotlin从小白到大神Day02 2020.7.13

内容

1.类与构造函数
2.构造函数中的参数
3.继承
4.多态
5.属性以及set/get方法
6.可空类型
7.懒加载和延迟加载

一.类与构造函数

注意:主构造函数与次构造函数的关系,它们之间调用的顺序
每个次构造函数都调用主构造函数,或者多个构造函数之间相互调用,但是最后一定会调用主构造函数,即 次构造函数 ————> 。。。————>次构造函数 ————> 主构造函数

test01

//类与构造函数
fun main(){
     
   var Me = Person1()//输出 我是init函数
}

//类的定义与Java中基本相同
class Person{
     

}

//kotlin中构造函数分两种,主构造函数和次构造函数
//注意:次构造函数必须显示调用主构造函数。
//其实对象还是主构造函数创建的,主构造函数和次构造函数之间构成一个类似于重载的关系
//构造函数表示方法①
class Person1(){
     
    init{
     
        //init可以理解为主构造函数要做的事情
        println("我是init函数")
    }
}
class Person2 constructor(){
     
    init{
     

    }
}

//构造函数表示方法②
class Person3(){
     
    init{
     

    }
    constructor(name : String):this(){
     
        //注意:次构造函数必须显示调用主构造函数。
    }

    constructor(name : String,age : Int):this(){
     

    }
}

test02

fun main(){
     
    //var person = Person("帅哥")
    //person.name//主构造函数中的参数在外部不能访问,这句话就是错的

    var test01 = Person1("贼帅")//输出 贼帅
    var test02 = Person1("贼帅",18)
    //先输出init里面的 贼帅 ,后输出次构造函数里面的 贼帅,18
    //说明先执行主构造函数,后执行次构造函数
}

//带有参数的主构造函数
class Person(name: String){
     
    val Myname:String = name//初始化属性的时候可以访问主构造函数中的参数
    init{
     
        //主构造函数的“做事儿区”也可以访问主构造函数中的参数
        println(name)
    }
}

//可以把次构造函数中的参数传给主构造函数
class Person1(name: String){
     
    init{
     
        println(name)
    }
    constructor(name: String,age: Int):this(name){
     
        println("$name,$age")
    }
}

二.构造函数中的参数

注意:参数可以属性化

fun main(){
     
    var person = Person("帅哥")
    println(person.name)//就会输出 帅哥 ,而不是和刚才一样报错了

    var person1 = Person1("贼帅")//因为第二个参数有默认值,所以在这里可以不传

    var person2_1 = Person2("妻子")//这时候,默认匹配第一个参数
    var person2_2 = Person2(wife = "妻子")//这样就实现了给第二个参数赋值
}

//刚刚说了,主构造函数中的参数外界是不能访问的,而且只能在init或者属性初始化的时候才能使用
//如果想改变这个局面,使主构造函数中的参数真正的作用域在它的整个类里面,而且外部也可以访问,就可以这样做
class Person(var name: String){
     //加val也可以,区别就是var和val的区别
    //如果是var,外界就可以更改
}
//它其实相当于执行了两步操作
class Person01(temp: String){
     
    var name: String = temp
}

//而且还可以在括号中给参数初始化
class Person1(var name: String,var wife: String = "没有"){
     
    //wife默认没有,到时候直接传第一个参数就可以
}
//如果两个参数都初始化了,但是你创建对象的时候只想传第二个参数,这时就要把名字带上
class Person2(var name: String = "张三",var wife: String = ""){
     
    /*在main里面就可以这样
    var person2_1 = Person2("妻子")//这时候,默认匹配第一个参数
    var person2_2 = Person2(wife = "妻子")//这样就实现了给第二个参数赋值
     */
}

三.继承

继承时要将父类变成“open”
重写方法时,要将父类相应的方法open,并且子类重写的方法前要加override

//在已有类的基础上添加新的方法和属性,在kotlin里面有两种方式
//1.继承,直接冒号后面跟着继承谁就可以,而且需要将父类 open
//2.函数扩展(后面要学)

open class Father(){
     
    //在kotlin里面类默认不能被继承
    //如果要继承,就在前面加上关键字:open
}
class Son() : Father(){
     
    //kotlin里面只能单继承,但是可以”间接“多继承
}

//当父类的构造方法中有参数时
open class Father1(name: String){
     

}
class son1(name: String) : Father1(name){
     //如果父类的参数有默认值了,就可以不用给了

}
//如果父类构造方法中的参数属性化了,那子类就可以直接访问了

//子类重写父类的方法时,要使用override修饰,而且要将被重写的方法open
open class Father2(){
     
    open fun work(){
     
        //方法默认不能被重写,如果想要重写,就加上open
        println("这里是父类的work方法")
    }
}

class Son2() : Father2(){
     
    override fun work(){
     
        //如果子类需要调用父类的方法,那么还是使用super
        super.work()
        println("这里是继承的work方法")
    }
}
fun main(){
     
   var son2 = Son2()
    son2.work()
    /*输出
     这里是父类的work方法
     这里是继承的work方法
     */
}

四.多态

多态,其实和Java中的基本一样,这里我把我的Java博客中对于多态的讲解拿到这里
多态讲解

五.属性以及set/get方法

注意:①属性声明的时候必须要初始化
②重写set/get方法的方式
③get方法不能私有化(为何get方法不能私有化?)

//定义属性可以有两种方式,默认定义属性时会自动创建对应的set和get方法
//如果变量是val,那就只有get方法,这一点很好理解
//第一种,直接在参数这里
class Person1(var name: String){
     

}
//第二种,在类里面,注意:这里属性声明的同时必须要初始化
class Person2(){
     
    //var name: String,这种就要报错
    var name: String = "初始化"//这样就可以
}

//重新set/get方法
class Person3(){
     
    var name: String = "啥都没有"
      //重写set方法(如果一句话能写完就用=,如果需要多句那就用{})
      set(value) {
     field = value.toUpperCase()}//这个value就是 =  后面的那个值
      //默认情况下,任何一个属性都有一个内部变量,名字就是field
      //这个变量只能在set/get方法里面调用(关于这个变量具体的知识点,我会查资料学习一下)

      //重写get方法(如果一句话能写完就用=,如果需要多句那就用{})
      get() = field.toUpperCase()

}

//set方法私有化
class Person4(){
     
    //外界不能更改,但是可以读取
    var password: String = "1234"
        private set
    //如果想外界既不能更改也不能访问,就可以直接在属性声明前面加private
    private var password1 = "1234"

    //外界不能读取,只能更改
    var password3 = "1234"
        //private get,这样会报错,应该是不可以,我会再查一下资料,找一下原因
}
fun main(){
     

    //默认定义属性时会自动创建对应的set和get方法
    var p1 = Person1("小王")
    p1.name = "不是小王"//set方法
    println(p1.name)//get方法,这里就输出 不是小王

    //如果对自动提供的set方法不满意,当然可以自己更改
    var p3 = Person3()
    p3.name = "triangle"//此时就调用你自己创建的set方法了
    println(p3.name)//输出 TRIANGLE



}

六.可空类型

一般来说,只要一开始用了可空类型,后面就要一直用了


//?  注意要跟昨天学的 ?: 做一下对比,其实都是?在起作用

//何时使用可空类型
//①声明变量时,不确定变量有没有值
//②接收Java的返回值时

//对于可空类型的对象,调用时必须使用?
//如果明确指定这个对象一定不是空,那么就可以加两个 !!,在?的位置(不要随便用)
fun main(){
     
    var tt: String? = null//?表示可空类型
    println(tt?.length)//如果tt是空的,那就不会执行后面的方法
    //这里就输出 null

    //println(tt!!.length)//这里就会报错
}

七.懒加载和延迟加载

注意懒加载必须要是常量

//懒加载:只能是常量
//当这个 常量 被调用的时候才会赋值
class Activity{
     
    val data: String by lazy {
     
        "图片"
    }

    fun showActivity(){
     
        println("下载的是: $data")
    }
}

//延迟加载
//先不初始化,但是必须在使用之前的某个位置初始化
class Activity1{
     
    lateinit var data: String

    fun show(){
     
        data = "图片"
        println("初始化后的data是 $data")//如果没有上面那一句,就会报错
    }
}
fun main(){
     
    //Activity().showActivity()//输出 下载的是: 图片
    Activity1().show()
}

你可能感兴趣的:(kotlin学习笔记,Kotlin)