Kotlin学习笔记(四):Kotlin中的类与对象

一、简介

Kotlin中使用关键字class 声明类,后面紧跟类名 。Kotlin中的类默认是public final的,所以如果不需要类为final的时候,需要使用open关键字修饰类,如果没有声明父类。则父类默认为Any类。

//定义一个空类
open class Animal

interface Run

//继承类或接口时,使用 : 隔开,父类和接口间使用 , 隔开
class Dog : Animal(), Run

二、构造函数

1. 主构造器

主构造器放在类名后,不能包含任何代码,初始化代码可以放在初始化代码段中,初始化代码段使用init关键字作为前缀。
注意:主构造器的参数可以在初始化代码段中使用,可以通过主构造器来定义属性并初始化属性值(可以是varval)。

class Dog constructor(val age: Int, val name: String){

    init {
        println("Dog $name is $age years old.")
    }

}

如果构造器有注解,或者有可见度修饰符,则constructor关键字是必须的,注解和修饰符放在它之前,否则constructor可以省略不写。

2. 创建实例

fun main(args: Array<String>) {
    val dog = Dog(2,"Irving")
}

3.次级构造函数

类的次级构造函数使用constructor修饰。

class Cat {
    
    constructor(age: Int, name: String){
        println("Cat $name is $age years old")
    }
    
}

如果类有主构造器,则每个次级构造函数都需要直接或间接的代理此主构造器。在同一个类中代理另一个构造函数使用this关键字。

class Cat(age: Int) {

    constructor(age: Int, name: String): this(age){
        println("Cat $name is $age years old")
    }

    constructor(age: Int, name: String, type: Int): this(age, name){
        println("Cat $name is $age years old")
    }
    
}

三、访问修饰符

  1. private:修饰类的时候,表示该类中所有成员都是私有的。修饰成员的时候,表示该成员是该类私有的。
  2. protected:只能用以修改类的成员,表示只有该类和它的子类可以访问该成员。
  3. public:所有类均可访问。
  4. internal:表示只有该模块(moudle)内的类能访问。

四、伴生对象

通过companion object声明伴生对象,必须写在一个类的内部,作为该类的伴生对象,编译器编译时会在该类中生成一个静态的Companion对象,然后调用该静态对象的成员。伴生对象中的属性和方法可以理解为Java中的静态变量和静态方法,可以直接通过类名.属性/方法调用,如果是Java类中调用时通过类名.Companion.属性/方法调用

	class Bird{

	    companion object {
	        const val BIRD_NAME = "Irving"
	
	        fun getBirdName(): String = BIRD_NAME 
	    }

	}

除了使用object关键字声明一个单例类之外,使用伴生对象可以很方便的创建单例对象。

	class Person{
	
	    companion object {
	        fun get(): Person = Holder.instance
	    }
	
	    private object Holder{
	        val instance = Person()
	    }
	
	}

五、Kotlin中的动态代理

Kotlin中通过使用by关键字可以很方便的使用动态代理。

interface People {
    fun sayHello()
}

//目标类
class Man : People {
    override fun sayHello() {
        println("Hello")
    }
}

//代理类
class Irving(people: People) : People by people 

fun main(args: Array<String>) {
    val irving = Irving(Man())
    irving.sayHello()
}

Kotlin会将动态代理编译为静态代理去调用,所以Kotlin的动态代理比Java的动态代理效率高,因为Java的动态代理本质上是通过反射去调用的。

六、数据类

可以使用data关键字声明一个数据类,数据类是public final的,所以不可以被继承(需要继承时可以使用密封类)。编译器会为数据类的所有属性生成getter()/setter()方法,并且会重写toString()hashCode()equals()copy()这些方法。

data class User(
    var id: Int,
    var name: String,
    var gender: Int
)

七、密封类

密封类可以理解为一个增强的枚举类,密封类和它的子类必须写在同一个文件中,增强的地方就是密封类的子类可以扩展,从而更加灵活。

sealed class Hello {
    object UP : Hello()
    object DOWN : Hello()
    object LEFT : Hello()
    object RIGHT : Hello()
    class Irving(var age: Int) : Hello()
}

fun test(hello: Hello) {
    when (hello) {
        Hello.UP -> println("UP")
        Hello.DOWN -> println("DOWN")
        Hello.LEFT -> println("LEFT")
        Hello.RIGHT -> println("RIGHT")
        is Hello.Irving -> println(hello.age)
    }
}

fun main(args: Array<String>) {
    test(Hello.Irving(11))
}
发布了167 篇原创文章 · 获赞 230 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/qq_39240270/article/details/104179107