1. 程式人生 > >android Kotlin 繼承、派生、介面、構造方式,方法、屬性重寫

android Kotlin 繼承、派生、介面、構造方式,方法、屬性重寫

前言

kotlin 作為google官方android 開發語言,大勢所趨,據傳到2018底kotlin要全面替代java在android中的地位,其實這個也不擔心畢竟kotin和java可以100%互操作。兩種語言進行編寫也是可以的。

Kotlin 繼承

1.使用 open 關鍵字進行修飾

2.主建構函式緊跟著在類後面宣告的函式

open class Person(var name : String, var age : Int){// 基類

}

class Student(name : String, age : Int, var no : String, var score : Int) : Person(name, age) {

}

// 二級建構函式

calss Student : Person {

    constructor(ctx: Context) : super(ctx) {
    } 

    constructor(ctx: Context, attrs: AttributeSet) : super(ctx,attrs) {
    }
}

另一種寫法,基類建構函式,次級建構函式

/**使用者基類**/
open class Person(name:String){
    /**次級建構函式**/
    constructor(name:String,age:Int):this(name){
        //初始化
println("-------基類次級建構函式---------") } } /**子類繼承 Person 類**/ class Student:Person{ /**次級建構函式**/ constructor(name:String,age:Int,no:String,score:Int):super(name,age){ println("-------繼承類次級建構函式---------") println("學生名: ${name}") println("年齡: ${age}") println("學生號: ${no}"
) println("成績: ${score}") } } fun main(args: Array<String>) { var s = Student("Runoob", 18, "S12345", 89) }

方法重寫

基類fun函式預設 final 修飾符,無法在子類進行重寫
需要加上 open 修飾符號

方法獲得,同名方法獲得

一個類從其他類或者介面(繼承實現來的方法),同名方法,在子類中必須顯示進行呼叫

 open class A {
    open fun f () { print("A") }
    fun a() { print("a") }
}

interface B {
    fun f() { print("B") } //介面的成員變數預設是 open 的
    fun b() { print("b") }
}

class C() : A() , B{
    override fun f() {
        super<A>.f()//呼叫 A.f()
        super<B>.f()//呼叫 B.f()
    }
}

fun main(args: Array<String>) {
    val c =  C()
    c.f();

}




    open class A {
    open fun f () { print("A") }
    fun a() { print("a") }
}

interface B {
    fun f() { print("B") } //介面的成員變數預設是 open 的
    fun b() { print("b") }
}

class C() : A() , B{
    override fun f() {
        super<A>.f()//呼叫 A.f()
        super<B>.f()//呼叫 B.f()
    }
}

fun main(args: Array<String>) {
    val c =  C()
    c.f();

}

屬性重寫

屬性重寫使用 override 關鍵字,屬性必須具有相容型別,每一個宣告的屬性都可以通過初始化程式或者getter方法被重寫:

open class Foo {
    open val x: Int get { …… }
}

class Bar1 : Foo() {
    override val x: Int = ……
}

你可以用一個var屬性重寫一個val屬性,但是反過來不行。因為val屬性本身定義了getter方法,重寫為var屬性會在衍生類中額外宣告一個setter方法
你可以在主建構函式中使用 override 關鍵字作為屬性宣告的一部分:

interface Foo {
    val count: Int
}

class Bar1(override val count: Int) : Foo

class Bar2 : Foo {
    override var count: Int = 0
}

Kotlin 介面

Kotlin 介面與 Java 8 類似,使用 interface 關鍵字定義介面,允許方法有預設實現:

interface MyInterface {
    fun bar()    // 未實現
    fun foo() {  //已實現
      // 可選的方法體
      println("foo")
    }
}

介面中的屬性

介面中的屬性只能是抽象的,不允許初始化值,介面不會儲存屬性值,實現介面時,必須重寫屬性:

interface MyInterface{
    var name:String //name 屬性, 抽象的
}

class MyImpl:MyInterface{
    override var name: String = "runoob" //過載屬性
}

函式重寫

實現多個介面時,可能會遇到同一方法繼承多個實現的問題。例如:
例項

interface A {
    fun foo() { print("A") }   // 已實現
    fun bar()                  // 未實現,沒有方法體,是抽象的
}

interface B {
    fun foo() { print("B") }   // 已實現
    fun bar() { print("bar") } // 已實現
}

class C : A {
    override fun bar() { print("bar") }   // 重寫
}

class D : A, B {
    override fun foo() {
        super<A>.foo()
        super<B>.foo()
    }

    override fun bar() {
        super<B>.bar()
    }
}

fun main(args: Array<String>) {
    val d =  D()
    d.foo();
    d.bar();
}

輸出結果為:

ABbar

例項中介面 A 和 B 都定義了方法 foo() 和 bar(), 兩者都實現了 foo(),
B 實現了 bar()。因為 C 是一個實現了 A 的具體類,所以必須要重寫 bar() 並實現這個抽象方法。
然而,如果我們從 A 和 B 派生 D,我們需要實現多個介面繼承的所有方法,並指明 D 應該如何實現它們。
這一規則 既適用於繼承單個實現(bar())的方法也適用於繼承多個實現(foo())的方法。