与 Java 一样,abstract
关键字用于在 Kotlin 中声明抽象类。抽象类不能被实例化(不能创建抽象类的对象)。但是,您可以从它们继承子类。
除非您显式使用 abstract
关键字将抽象类成员(属性和方法)标记为抽象,否则它们是非抽象的。让我们看一个例子
abstract class Person { var age: Int = 40 fun displaySSN(ssn: Int) { println("My SSN is $ssn.") } abstract fun displayJob(description: String) }
这里,
- 创建了一个抽象类
Person
。您不能创建该类的对象。 - 该类有一个非抽象属性 age 和一个非抽象方法
displaySSN()
。如果您需要在子类中重写这些成员,它们应被标记为open
关键字。 - 该类有一个抽象方法
displayJob()
。它没有实现,必须在其子类中被重写。
注意:抽象类始终是 open 的。您不需要显式使用 open
关键字来从它们继承子类。
示例:Kotlin 抽象类和方法
abstract class Person(name: String) {
init {
println("My name is $name.")
}
fun displaySSN(ssn: Int) {
println("My SSN is $ssn.")
}
abstract fun displayJob(description: String)
}
class Teacher(name: String): Person(name) {
override fun displayJob(description: String) {
println(description)
}
}
fun main(args: Array<String>) {
val jack = Teacher("Jack Smith")
jack.displayJob("I'm a mathematics teacher.")
jack.displaySSN(23123)
}
运行程序后,输出将是
My name is Jack Smith. I'm a mathematics teacher. My SSN is 23123.
在这里,类 Teacher
是从抽象类 Person
派生的。
实例化了一个 Teacher 类的对象 jack。在创建它时,我们将 "Jack Smith"
作为参数传递给了主构造函数。这会执行 Person
类的初始化代码块。
然后,使用 jack 对象调用 displayJob()
方法。请注意,displayJob()
方法在基类中声明为抽象,并在派生类中重写。
最后,使用 jack 对象调用 displaySSN()
方法。该方法是非抽象的,并在 Person 类中声明(未在 Teacher
类中声明)。
推荐阅读: Kotlin 接口
Kotlin 接口与抽象类相似。但是,接口不能存储状态,而抽象类可以。
这意味着,接口可以有属性,但它需要是抽象的或提供访问器实现。而抽象类的属性不一定必须是抽象的。