一、类和对象:
- 在Kotlin中,使用
class
关键字定义类,使用object
关键字定义对象。 - 类是对象的蓝图,用于描述对象的属性和行为,而对象则是类的一个实例。
- 类可以包含属性(成员变量)和方法(成员函数)。
代码演示:
// 定义一个简单的类
class Person(val name: String, var age: Int) {
// 成员函数
fun speak() {
println("My name is $name, I'm $age years old.")
}
}
fun main() {
// 创建对象并调用成员函数
val person = Person("Alice", 25)
person.speak()
}
运行结果:
My name is Alice, I'm 25 years old.
二、继承:
- Kotlin支持单继承,一个子类只能继承自一个父类。
- 使用
:
符号来指定继承关系,如class SubClass : SuperClass
。 - 子类可以重写父类的方法和属性,使用
override
关键字进行标记。
代码演示:
// 继承
open class Animal(val name: String) {
open fun makeSound() {
println("$name makes a sound.")
}
}
class Dog(name: String) : Animal(name) {
override fun makeSound() {
println("Dog $name barks.")
}
}
fun main() {
// 创建Animal对象并调用makeSound方法
val animal = Animal("Lion")
animal.makeSound()
// 创建Dog对象并调用makeSound方法
val dog = Dog("Bobby")
dog.makeSound()
}
运行结果:
Lion makes a sound.
Dog Bobby barks.
三、接口:
- Kotlin支持接口的定义和实现,接口可以包含抽象方法和属性。
- 使用
interface
关键字定义接口,使用implement
关键字实现接口。 - 一个类可以实现多个接口,通过逗号分隔。
代码演示:
// 接口
interface Shape {
fun calculateArea(): Double
}
class Rectangle(private val width: Double, private val height: Double) : Shape {
override fun calculateArea(): Double {
return width * height
}
}
fun main() {
// 接口示例
val rectangle = Rectangle(5.0, 3.0)
val area = rectangle.calculateArea()
println("The area of the rectangle is $area")
}
运行结果:
The area of the rectangle is 15
四、封装和访问控制:
- Kotlin提供了四种访问控制修饰符:
private
、protected
、internal
和public
。 - 默认情况下,成员都是
public
可见性的。 - 使用
private
修饰符限制成员只能在类内部访问,使用protected
修饰符允许子类访问。
java与kotlin对比:
代码演示:
class Person(private val name: String, protected var age: Int) {
fun introduce() {
println("My name is $name.")
}
fun updateAge(newAge: Int) {
age = newAge
}
}
class Employee(name: String, age: Int, private val company: String) : Person(name, age) {
fun work() {
println("$name works at $company.")
}
}
fun main() {
val person = Person("Alice", 25)
// 访问private属性,只能在类内部访问
// person.name // 编译错误:Unresolved reference: name
person.introduce()
val employee = Employee("Bob", 30, "ABC Company")
// 访问protected属性,子类可以访问
// employee.age // 编译错误:Unresolved reference: age
employee.work()
// 修改age属性
employee.updateAge(32)
employee.work()
}
在上述代码中,我们定义了一个Person类和一个Employee类。Person类有一个私有的name属性和一个受保护的age属性。Employee类继承自Person类,拥有所有从父类继承而来的属性和方法,并且还有一个私有的company属性。
在main函数中,我们创建了一个Person对象和一个Employee对象。我们无法直接访问Person对象的私有属性name,也无法直接访问Employee对象的受保护属性age,因为这些属性的可见性受到限制。但我们可以通过调用公共的成员函数来间接访问这些属性。
通过在Employee类中调用父类Person的updateAge方法,我们成功修改了age属性的值。
运行结果:
My name is Alice.
Bob works at ABC Company.
Bob works at ABC Company.
五、属性和字段:
- Kotlin中的属性可以自动为字段生成getter和setter方法。
- 可以使用
val
关键字定义只读属性(只有getter),使用var
关键字定义可变属性(包括getter和setter)。 - 也可以自定义属性的getter和setter方法。
代码演示:
package com.example.kotlin
class Person {
var height: Double = 170.0 // 初始化属性
var isTall: Boolean
get() {
return height >= 180 // 自定义getter方法
}
set(value) {
height = if (value) {
185.0 // 自定义setter方法
} else {
170.0
}
}
}
fun main() {
val person = Person()
println(person.isTall) // 调用自定义的getter方法判断是否高个子
println(person.height)
person.isTall = true // 调用自定义的setter方法将身高设置为185
println(person.height)
}
运行结果:
六、数据类:
- 数据类是Kotlin提供的一种特殊类型的类,用于存储和操作数据。
- 在数据类中,编译器会自动生成equals()、hashCode()、toString()等方法。
- 使用data class关键字定义数据类。
代码演示:
data class Person(val name: String, val age: Int)
fun main() {
val person1 = Person("John", 25)
val person2 = Person("John", 25)
println(person1) // 调用自动生成的toString()方法
println(person1 == person2) // 调用自动生成的equals()方法
val person3 = person1.copy(age = 30) // 使用copy()方法复制对象并修改其中的属性
println(person3)
}
运行结果:
七、扩展函数和扩展属性:
- Kotlin允许对已有的类添加新的函数和属性,称之为扩展函数和扩展属性。
- 使用
fun ClassName.methodName()
来定义扩展函数。 - 使用
val ClassName.propertyName
来定义扩展属性。
代码演示:
// 定义一个String类型的扩展函数
fun String.addWelcomeMessage(): String {
return "Welcome, $this!" // 在字符串前面添加欢迎消息
}
// 定义一个Int类型的扩展属性
val Int.isEven: Boolean
get() = this % 2 == 0 // 判断整数是否为偶数
fun main() {
val name = "John"
println(name.addWelcomeMessage()) // 调用扩展函数为字符串添加欢迎消息
val number = 6
println(number.isEven) // 调用扩展属性判断整数是否为偶数
}