Kotiln類和繼承

Kotiln類和繼承

類(class)

Kotlin中,使用class關鍵字生命一個類。類聲明由類名,類頭(指定其類型參數,主構造函數等)和大括號括起來的類體組成。

class MyClass public constructor(arg1:String){

}

構造器

Kotlin中,一個類可以有一個主構造函數或和一個或多個次構造函數。主構造函數是類頭的一部分,跟在類名(和可選的類型參數)後面,如果主構造函數沒有任何註解或可見性修飾符,可以省略constructor關鍵字。

主構造函數

主構造函數不包含任何的代碼,初始化代碼可以放到init關鍵字修飾的初始化塊中

主構造函數中的參數可以在初始化塊,或類體內聲明的屬性初始化器中使用

class MyClass (arg1:String){
  var str:String=arg1
    //初始化塊
    init {
        print(arg1)
    }
}

第二構造函

類也可以聲明前綴有constructor的次構造函數,如果類有主構造函數,每個次構造函數都要委託給主構造函數,可以直接委託,也可以通過別的次構造函數間接委託。委託到同一個類中的另一個構造函數,用this關鍵字即可。

class MyClass (var arg1:String){

    constructor():this("")//次構造函數

}

在主構造器中可以使用var和val,但是在第二構造函函數中不能使用var和val,這就意味着第二構造函數都是隻讀的,不能在構造器內部改變參數的值

默認參數

Java不支持默認參數,因爲JVM不支持,但是Kotlin函數支持默認參數,讓我們看一個簡單的例子

class MyClass (val bill:String = "Bill",var value : Float = 20.4F){


}

如果使用MyClass可以直接使用MyClass()。bill和value就會使用默認值

類成員

Kotlin中可以包含多種成員,如屬性、函數、嵌套類等

屬性的用法

1 . 屬性的基本用法

class MyClass{
    var name:String = "a"
    val value :Int = 20

}

2 . 屬性的getter和setter形式

    //  屬性的get和set函數

class Customer
{
    var mValue:Int =0
    //  只讀屬性
    val name:String
    get() = "Bill"

    var value:Int = 0
      get()
      {
          println("value.get")
         // return mValue
          return field
      }
      set(value:Int)
      {
          println("value.set")
          field = value
      }
}

3 . field
Kotlin爲我們提供了更便捷的方式解決保存屬性值得問題,field。在屬性getter和setter中,可以將field當做成員變量使用,也就是通過field讀寫屬性值

函數

在Kotlin中函數既可以在類外部定義,也可以在類內部定義。如果是前者,是全局函數,如果是後者,是類成員函數。無論函數在哪定義,語法規則基本是一樣的。函數也支持默認參數值,帶默認參數的必須是最後幾個參數,也就是說如果某個參數帶默認值,那麼該參數後面所有的參數都必須有默認值

package testclass.testinterface
//  函數
//  全局函數(在類的外部定義)
//  類成員函數(在類的內部定義)

// 1. 參數的默認值
// 包含默認值的參數應該在最後
// 2. 命名參數
// 3. 可變參數,需要用vararg表示參數爲可變參數
// 4. 函數的單行表達式
// 5. 嵌套函數
class QACommunity1
{
    // schema參數有默認值
    fun printQACommunity(url:String, schema:String="https",value:Int = 0)
    {
        println("${schema}://${url}")
    }
}
class Person1
{
    fun process(value:Int, name:String = "Bill", age:Int = 30, salary:Float = 4000F)
    {
        println("value:${value}, name:${name}, age:${age}, salary:${salary}")
    }
}
class Persons
{
    // persons爲可變參數,課傳入任意多個Person1對象
    fun addPersons(vararg persons:Person):List<Person>
    {
        val result = ArrayList<Person>()
        for(person in persons)
        {
            result.add(person)
        }
        return result
    }
}
fun getName():String = "Bill"
/*
fun getName():String
{
    return "Bill"
}
 */
fun main(args: Array<String>)
{
    QACommunity1().printQACommunity("geekori.com");
    //Person1().process(30,"Bill", 30, 12000F)
    //  命名參數
    Person1().process(30,salary = 12000F,name = "Mary")

    //  可變參數
    var persons = Persons().addPersons(Person("Bill"), Person("Mike"), Person("John"))
    for(person in persons)
    {
        println(person.name)
    }

    //  函數的單行表達式
    println(getName())

    // 嵌套函數
    fun process(age:Int)
    {
        println("age:${age}")
        fun process1()
        {

        }
    }
    process(40)

嵌套類

所謂嵌套類,就是類中定義的類

//  嵌套類
class Outer
{
    private val bar:Int = 20
    // 嵌套類
    inner class Nested
    {
        fun foo() = bar
    }
    fun process()
    {
        println(Nested())
    }
}

嵌套類可以使用inner聲明,這樣可以通過外部類(包含嵌套類的類)的實例引用嵌套類

修飾符(作用域)

  • public:默認,總是可見
  • internal:同模塊可見
  • private:聲明範圍與同模塊的子作用域可見
  • protected:類似於private,但對子類也可見

繼承

Kotlin中所有的類都有一個共同的超累類Any,對於沒有超類型聲明的類是默認超類。Any類不是java.lang.Object類,它只有equals,hashCode(),toString()3個成員方法。與Java不同,Kotlin通過“:”來繼承。

open class Parent
{
    protected var mName:String = "Bill"

     fun getName():String {
         return mName
     }
}
class Child : Parent()
{
    fun printName()
    {
        println(getName())
    }
}

要顯式聲明一個超類,可以把類型放到類頭的冒號之後,如果該基類有一個主構造函數,則其基類必須用主構造函數的參數就地初始化:

class B constructor(arg: String):A(arg){

}
  • 在kotlin中,不僅類默認是不可繼承的,連方法默認也是不可重寫的。因此,如果要在子類中重寫方法,就需要在父類相應的方法前面加open關鍵字,而且要在子類重寫的方法前面加override關鍵字。
  • 在kotlin中,val屬性可以被重寫爲var屬性,但反過來不可以
open class Parent
{
    protected var mName:String = "Bill"
    open fun function()
    {

    }
     open val name:String = "Mary"
        get()
        {
            println("獲取Parent.name屬性值")
            return field
        }
}
class Child : Parent()
{
    fun printName()
    {
        println(mName)
    }

     override var name: String = "Mike"
        get()
        {
            println("獲取Child.name屬性")
            return field
        }
    set(value)
    {
        field = value
        println("Child.name被寫入")
    }
}

接口

  • 在kotlin中接口與Java雷士,使用interface關鍵字聲明。一個類可以實現多個接口,實現的方法和類繼承相同。而且接口中的屬性和方法都是open的。
  • 在kotlin中,允許接口的方法包含默認的方法體。對於有方法體的接口方法,並不要求一定重寫該方法。
//  對象和委託:對象表達式
//  Kotlin中的對象是爲了代替Java中的匿名類
open class KotlinClass(name:String)
{
    open var name = name
    open fun verify()
    {
        println("verify")
    }
}
interface MyInterface
{
    fun closeData()
    {
        println("closeData")
    }
}
fun process(obj:KotlinClass)
{
    obj.verify()
    if(obj is MyInterface)
    {
        obj.closeData()
    }
}
fun main(args: Array<String>)
{
    process(object :KotlinClass("John"),MyInterface{
        override fun verify() {
            println("object verify")
        }
    });
    //  直接建立對象
    fun foo()
    {
        val obj = object
        {
            var x:Int = 10
            var y:Int = 20
        }
        println(obj.x + obj.y)
    }
    foo()
}
發佈了46 篇原創文章 · 獲贊 23 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章