企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# 1. 类的定义 类的定义和`Java`中类似,比如下面的案例: ~~~ class Person { private var name: String? = null private var age: Int? = null constructor(){ this.name = "张三" this.age = 20 } constructor(name: String, age: Int) { this.name = name this.age = age } override fun toString(): String { return "Person(name=$name, age=$age)" } } fun main() { var person: Person = Person() println(person) } ~~~ 结果: ``` Person(name=张三, age=20) ``` 需要注意的是,上面的两种构造函数的写法都是**次构函数**。`constructor`关键字定义,只不过次构函数位于类体中。对应的还有一类叫做**主构函数**,如下: ~~~ class Person constructor(){ private var name: String? = null private var age: Int? = null init { this.name = "张三" this.age = 20 } override fun toString(): String { return "Person(name=$name, age=$age)" } } ~~~ 从上面的案例可以看出,**主构函数**定义在类声明的这一行代码,且需要结合`init`代码块进行执行。不妨在下一个案例中我们将主构函数和次构函数均定义在类中: ~~~ class Person constructor(){ private var name: String? = null private var age: Int? = null init { this.name = "张三" this.age = 20 } constructor(name: String, age: Int): this() { this.name = name this.age = age } override fun toString(): String { return "Person(name=$name, age=$age)" } } fun main() { var person: Person = Person("李四", 23) println(person) } ~~~ 需要注意的是,在次构函数定义的时候,次构造函数必须调用主构造函数,也就是`次构函数:this(参数列表)`。 # 2. 继承 - 如果想声明一个类继承另一个类,则需要使用英文冒号“`:`”; - `Kotlin`中的所有类都默认使用`final`关键字修饰,不能被继承,因此,当继承某个类时,需要在这个类的前面加上`open`关键字; 比如下面的案例: ~~~ open class Person constructor(){ protected var name: String? = null protected var age: Int? = null init { this.name = "张三" this.age = 20 } constructor(name: String, age: Int): this() { this.name = name this.age = age } override fun toString(): String { return "Person(name=$name, age=$age)" } } class Student constructor(name: String, age: Int): Person() { init { this.name = name this.age = age } } fun main() { var person: Student = Student("李四", 23) println(person) } ~~~ 结果: ``` Person(name=李四, age=23) ``` 但是我们期望最终输出的信息为`Student`的信息,故而这里我们需要对`toString`进行重写。在`Kotlin`中被重写的属性或者方法前边需要使用“`override`”关键字标识。且在父类中需要被重写的属性和方法前面必须使用`open`关键字来修饰。比如: ~~~ open class Person constructor(){ protected open var name: String? = null protected var age: Int? = null init { this.name = "张三" this.age = 20 } constructor(name: String, age: Int): this() { this.name = name this.age = age } open override fun toString(): String { return "Person(name=$name, age=$age)" } } class Student constructor(name: String, age: Int): Person() { protected override var name: String? = null init { this.name = name this.age = age } override fun toString(): String { return "Student(name=$name, age=$age)" } } fun main() { var person: Student = Student("李四", 23) println(person) } ~~~ # 3. 嵌套类 嵌套类和`Java`中内部类类似,但是该类不能访问外部类的成员,内部类指的是可以用`inner`标记以便能够访问外部类的成员。 # 4. 枚举类 比如: ~~~ enum class Option{ GET, PUT, DELETE } ~~~ 当然可以写一个构造函数,并设置对应的值: ~~~ enum class Option(number: Int){ GET(0), PUT(1), DELETE(2) } fun main() { var opt = Option.PUT println(opt.name) println(opt.ordinal) } ~~~ 结果: ``` PUT 1 ``` # 5. 数据类 在`Java`程序中,一般会用一些类来保存一些数据或者对象的状态,习惯上将这些类称为`bean`类或`entity`类或`model`类。在`Kotlin`中,专门处理这些数据的类被称为数据类,用关键字`data`进行标记。需要注意的是: - 数据类中的主构造函数中传递的参数必须用`val`或`var`来修饰。 - 数据类不可以用`abstract`、`open`、`sealed`或`inner`关键字来修饰。 - 数据类的主构造函数至少有一个参数,如果需要一个无参的构造函数,可以将构造函数中的参数都设置为默认值。 ~~~ data class Option(var number: Int){ } fun main() { var opt = Option(2) println(opt) // Option(number=2) println(opt.number) // 2 } ~~~ # 6. 单例类 在`Kotlin`中,单例模式是通过`object`关键字来完成的,通过`object`修饰的类即为单例类,单例类在程序中有且仅有一个实例。 ~~~ object Singleton{ var name = "Hello" fun getName(){ println(name) } } fun main() { Singleton.getName() //Hello } ~~~ 这里没有创建`Singleton`对象的实例,而是采用类似`Java`中静态方法的调用。且注意到这里使用`object`关键字修饰即可,不需要`Java`中那么麻烦。 > 直接通过“类名.成员名”的形式调用类中的属性与函数,不需要创建该类的实例对象,这是因为通过object关键字创建单例类时,默认创建了该类的单例对象。 # 7. 伴生对象 在`Kotlin`中没有静态变量,取而代之的是伴生对象。伴生对象是在类加载时初始化,生命周期与该类的生命周期一致。 定义伴生对象是通过“`companion`”关键字标识的,由于每个类中有且仅有一个伴生对象,因此也可以不指定伴生对象的名称,并且其他对象可以共享伴生对象。 在调用伴生对象时分两种情况,具体如下。 (1)有名称:调用方式为“`类名.伴生对象名.成员名`”或“`类名.成员名`”。 (2)无名称:调用方式为“`类名.Companion.成员名`”或“`类名.成员名`”。 比如: ~~~ class Person{ var name = "Hello" companion object UUID{ fun generateUUID(): Int { return LocalDateTime.now().second } } fun getName(){ println("UserName:${name}, UUID: ${Person.UUID.generateUUID()}") } } fun main() { Person().getName() } ~~~