# 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()
}
~~~
- Kotlin语言基础
- Kotlin的简介
- Kotlin的变量和常见数据类型
- Kotlin的区间
- Kotlin的位运算
- Kotlin的容器
- Kotlin类型检查
- Kotlin的空值处理
- Kotlin的函数
- Kotlin的类
- Kotlin的委托
- Kotlin的延迟加载
- Kotlin的异常
- Kotlin的Lambda表达式
- Kotlin的高阶函数
- Kotlin的标准库中的高阶函数
- Kotlin的泛型
- Kotlin的表达式
- Kotlin的解构
- Kotlin的运算符重载
- Kotlin语言中级
- Kotlin的扩展函数
- Kotlin的扩展属性
- Kotlin的infix关键字
- Kotlin的DSL
- Kotlin的一些注解(和Java互调用)
- Kotlin的lateinit和by lazy
- Kotlin的反射
- Kotlin的匿名接口
- 安卓中的Kotlin
- 数据库操作Room