今天是面向對象的最後一節,下一節爲函數式編程。
一、繼承
在面向對象中繼承使用的特別多,當你有幾個類,屬性和函數差不多。你就可以定義一個父類,然後繼承它,拿到它的屬性和函數,不用一直重複寫。
在Kotlin中繼承使用:來表示
class Student : Person() {
}
但是繼承的父類必須是open的,也就是說kotlin中所有類默認是find的,而open就是取消自動find的意思。
open class Person {
var name: String? = "人"
var age = 20
fun hand() {
println("hand")
}
}
所有類默認繼承Any這個類,類似Java中的object。Kotlin和Java都是單繼承多實現的規則,只允許繼承一個父類,但可以實現很多接口。
重載和重寫
在Java中也有重載和重寫的概念。它們發生在繼承得基礎上,只有繼承關係後纔會出現。
重載:函數名相同,參數列表不同
重寫:函數名相同,參數列表相同
特點:他們都需要函數名相同
this和super
this是本類,super是父類
open class Person() {
open var name="Person"
}
class Student() : Person() {
override var name = "Student"
fun test() {
println(super.name)
println(this.name)
}
}
fun main(args: Array<String>) {
var student=Student()
student.test()
}
結果:
二、多態
同一種功能多種表達形態。
多態發生的條件
- 繼承:必須要有繼承關係
- 重寫:子類重寫父類函數
- 聲明對象是父類類型,對象是子類實例
看個例子,容易明白。
open class Person() {
open fun speak() {
println("說話")
}
}
發生了繼承關係,重寫了父類的函數
class Student : Person() {
override fun speak() {
println("學生在說話")
}
}
聲明對象是父類類型,對象是子類實例
fun main(args: Array<String>) {
var person: Person = Student()
person.speak()
}
打印結果爲:
這就是多態
類型判斷 is和!is
在Kotlin中使用is或者!is來判斷類型
fun main(args: Array<String>) {
var person: Person = Student()
println(person is Person)
}
結果
!is 和is的意思是相反的意思
類型轉換 as 和!as
as使用於引用類型轉換的,但是隻能用於屬於同一種繼承關係纔可以。
fun main(args: Array<String>) {
// 向上轉型
var p = Student()
var pp: Person = p
//向下轉型
var p1: Person = Student()
var p11 = p1 as Student
//錯誤
var p2 = Person()
// var p22 = p2 as Student //這裏異常
//as?的使用
var p3 = Person()
var p33 = p3 as? Student //這裏就不會異常,會返回null
println(pp)
println(p11)
println(p33)
}
密封類
密封類可以限制它子類的個數,密封類是一種抽象類。
sealed class A
class AA : A()
class AAA : A()
sealed是聲明密封類的關鍵字,下面則是它的子類。
抽象類
聲明一個抽象類很簡單
abstract class Person() {
abstract fun test1()
}
抽象類可以有自己的屬性、函數、構造方法
abstract class Person(var name: String) {
abstract fun test1()
var age = 0
fun test2() {
}
}
實現一個抽象類,必須重寫它抽象函數、屬性。
抽象類不能被實例化即使它有構造函數
接口
接口則是比抽象類更抽象的對象,它只能有抽象的屬性和函數。
和Java不同Kotlin中的接口可以有具體的函數和屬性,並不是只能抽象的。
interface Demo1 {
var int: Int
fun test(string: String) { //具體的函數
string + int
}
fun test2() //抽象的函數
}
一個類可以實現多個接口,接口可以繼承接口。當然接口本來都是抽象的,所以繼承了別的接口,你可以選擇重寫或者不重寫父接口的函數。