如何查网站开发环境,新网登录网站后台,设计工作室名片,国家备案网1 前言 Kotlin 是面向对象编程语言#xff0c;与 Java 语言类似#xff0c;都有类、对象、属性、构造函数、成员函数#xff0c;都有封装、继承、多态三大特性#xff0c;不同点如下。
Java 有静态#xff08;static#xff09;代码块#xff0c;Kotlin 没有#xff1…1 前言 Kotlin 是面向对象编程语言与 Java 语言类似都有类、对象、属性、构造函数、成员函数都有封装、继承、多态三大特性不同点如下。
Java 有静态static代码块Kotlin 没有Java 有静态static函数Kotlin 没有Java 构造函数名与类名相同Kotlin 构造函数名为 constructorKotlin 有初始化代码块initJava 没有Kotlin 有主构造函数Java 没有。 在包下面右键依次点击【New → Kotlin Class/File】输入类名后创建 Kotlin 类文件。 如下创建了一个 Student.kt 文件。
package com.zhyan8.kotlinStudyclass Student {
} 笔者为简化代码将定义的类与 main 函数放在同一个文件中了。
2 类的结构 如下Student 类是一个自定义的类里面包含了一个类的基本结构。
fun main() {var stu1 Student()stu1.study()println(-----------------------------------------)var stu2 Student(li si, 23)
}class Student {private var name: String zhang san // 属性get() { // name的getter函数return field}set(value) { // name的setter函数field value}private var age: Int 18 // 属性init { // 初始化代码块, 在构造函数前执行println(Student init, name$name, age$age)}constructor() { // 无参构造函数println(create-1, name$name, age$age)}constructor(name: String, age: Int) { // 有参构造函数println(create-2, name$name, age$age)this.name namethis.age age}fun study() { // 成员函数println(study...)}
} 说明init 代码块可以有多个按照从前往后的顺序执行上述构造函数都是次要构造函数第 3 节中会介绍主构造函数。 运行程序后打印如下。
Student init, namezhang san, age18
create-1, namezhang san, age18
study...
-----------------------------------------
Student init, namezhang san, age18
create-2, nameli si, age23
3 主构造函数 主构造函数是紧接在类名后面的构造函数次要构造函数是类体内部定义的构造函数它们的区别如下。
主构造函数主构造函数只能存在一个只有函数声明没有函数体可以在入参中定义类的属性会自动进行类属性的初始化赋值。次要构造函数次要构造函数可以存在多个可以自定义函数体也可以无函数体不能在入参中定义类属性当类有主构造函数时所有次要构造函数必须直接或间接地调用主构造函数。
3.1 无参主构造函数
fun main() {var stu1 Student()println(-----------------------------------------)var stu2 Student(zhang san)
}class Student() { // 等价与: class Student constructor()init { // 初始化代码块, 在构造函数前执行println(init)}constructor(name: String): this() {println(constructor, name$name)}
} 运行程序后打印如下。
init
-----------------------------------------
init
constructor, namezhang san class Student() 等价于 class Student constructor()如果需要对主构造函数的权限进行控制可以修改如下。
class Student private constructor() {...
}
3.2 有参主构造函数普通参数
fun main() {var stu1 Student(xiao ming, 23)println(-----------------------------------------)// stu1.name // 编译报错, name不是成员属性var stu2 Student()
}class Student(name: String, age: Int) {init {println(init, name$name, age$age)}constructor(): this(zhang san, 18) {println(constructor)}
} 运行程序后打印如下。
init, namexiao ming, age23
-----------------------------------------
init, namezhang san, age18
constructor
3.3 有参主构造函数成员属性
fun main() {var stu1 Student(xiao ming, 23)println(stu1.name${stu1.name}, stu1.age${stu1.age})println(-----------------------------------------)var stu2 Student()println(stu2.name${stu2.name}, stu2.age${stu2.age})
}class Student(var name: String, var age: Int) {init {println(init, name$name, age$age)}constructor(): this(zhang san, 18) {println(constructor)}
} 说明在主构造函数中通过给入参添加 var变量或 val常量修饰使得参数变为成员属性在次要构造函数中不能给入参添加 var 或 val 修饰。 运行程序后打印如下。
init, namexiao ming, age23
stu1.namexiao ming, stu1.age23
-----------------------------------------
init, namezhang san, age18
constructor
stu2.namezhang san, stu2.age18 如果用户想修改入参属性的权限可以在 var 或 val 前面添加权限修饰符。
class Student(private val name: String, protected var age: Int) {...
}
4 封装 封装是指将相关联的属性和函数封装到同一个类中并且可以控制这些属性和函数的访问权限它通过隐藏内部细节和提供清晰的接口提高了代码的安全性、可维护性和可理解性它是面向对象编程中的重要概念之一。 在 Kotlin 中有四种访问权限修饰符private、protected、internal 和 public。这些修饰符控制了代码中类、函数、属性等成员的可见性和访问权限。
private最严格的访问权限只在声明它的类或文件内可见。protected与 Java 中的 protected 类似不同之处在于 Kotlin 中 protected 修饰的成员仅对其子类可见但不一定在同一个文件中可见。另外protected 在 Kotlin 中不能直接应用于顶层函数和属性直接定义在文件中的函数和属性而不是在类中定义的。internal模块内可见模块是编译在一起的一组 Kotlin 文件internal 修饰的成员对于同一模块中的任何其他代码都是可见的但对于其他模块中的代码是不可见的。public最宽松的访问权限public 成员可以被任何地方的代码访问如果没有指定访问修饰符默认为 public。
5 继承 继承是指一个类称为子类或派生类基于另一个类称为父类或基类创建新类子类继承了父类的属性和函数并且可以在此基础上进行扩展或修改它是面向对象编程中的重要概念之一。在 Kotlin 中继承使用冒号:来表示Any 类是所有类的基类。 类的初始化顺序如下。
父类主构造函数父类 init 代码块父类次要构造函数子类主构造函数子类 init 代码块子类次要构造函数
5.1 子类无主构造函数
fun main() {var stu Student(zhang san, 23, 1001)
}open class People(var name: String) {init {println(People init, name$name) // 1}constructor(name: String, age: Int): this(name) {println(People constructor, name$name, age$age) // 2}
}class Student : People {init {println(Student init, name$name) // 3 (此处不能访问age和id)}constructor(name: String, age: Int, id: Int) : super(name, age) {println(Student constructor, name$name, age$age, id$id) // 4}
} 说明子类必须直接或间接调用一下父类的一个构造函数否则编译报错。 运行程序后打印如下。
People init, namezhang san
People constructor, namezhang san, age23
Student init, namezhang san
Student constructor, namezhang san, age23, id1001
5.2 子类有主构造函数
fun main() {var stu Student(zhang san, 23, 1001)
}open class People(var name: String) {init {println(People init, name$name) // 1}constructor(name: String, age: Int): this(name) {println(People constructor, name$name, age$age) // 2}
}class Student(name: String, var age: Int) : People(name, age) {init {println(Student init, name$name, age$age) // 3 (此处不能访问id)}constructor(name: String, age: Int, id: Int): this(name, age) {println(Student constructor, name$name, age$age, id$id) // 4}
} 说明子类必须直接或间接调用一下父类的一个构造函数否则编译报错当子类中有主构造函数时子类中的次要构造函数。 运行程序后打印如下。
People init, namezhang san
People constructor, namezhang san, age23
Student init, namezhang san, age23
Student constructor, namezhang san, age23, id1001
6 多态 多态是指同一个函数可以在不同的对象上表现出不同的行为这种行为通常通过继承和接口来实现。多态使得代码更加灵活和可扩展是面向对象编程中的重要概念之一。
6.1 覆盖函数
fun main() {var peo: People Student(li si, 25, 1002)peo.say()
}open class People(var name: String, var age: Int) {init {println(People init, name$name, age$age)}open fun say() {println(People say)}
}class Student(name: String, age: Int, var id: Int) : People(name, age) {init {println(Student init, name$name, age$age, id$id)}override fun say() {println(Student say)}
} 运行程序后打印如下。
People init, nameli si, age25
Student init, nameli si, age25, id1002
Student say
6.2 覆盖属性
fun main() {var peo : People Student()peo.doSomething()
}open class People {open var name: String zhang sanfun doSomething() {println(doSomething, name$name)}
}class Student : People() {override var name: String li si
} 运行程序后打印如下。
doSomething, nameli si
6.3 类型智能转换
fun main() {var peo: People Student()// peo.study() // 编译报错if (peo is Student) {peo.study() // 智能转换为Student}
}open class People {
}class Student : People() {fun study() {println(study...)}
} 说明Java 没有智能转换特性需要进行强制类型转换。
7 抽象类 使用 abstract 修饰的类称为抽象类抽象类中可以有抽象属性和函数这些属性和函数被添加了 abstract 修饰符父类不能实现子类必须重写实现子类如果也是抽象类除外。抽象类不能被实例化只能实例化其具化子类抽象类中允许有具化的属性和函数。
fun main() {// var peo People() // 编译报错, 抽象类不能被实例化var stu Student()stu.say()
}abstract class People {abstract var name: Stringabstract fun say()
}class Student : People() {override var name: String xiao minoverride fun say() {println($name: Hello)}
} 说明Java 中只有抽象函数没有抽象属性。 运行程序后打印如下。
xiao min: Hello
8 接口 接口与抽象类有些类似接口里只有抽象属性和函数函数允许有默认实现属性不能Kotlin 中允许一个类实现多个接口但最多只能继承一个类。
fun main() {var c C(xxx, yyy)c.aFun()c.bFun()
}interface A {var x: Stringfun aFun()
}interface B {var y: Stringfun bFun()
}class C(override var x: String, override var y: String) : A, B {override fun aFun() {println(aFun, x$x)}override fun bFun() {println(bFun, y$y)}
} 运行程序后打印如下。
aFun, xxxx
bFun, yyyy