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()
}

猜你喜欢

转载自blog.csdn.net/yulu5216/article/details/79056564