Kotlin(三) 类 和 函数

前面两篇文章简单介绍了对象的声明和一些控制流的用法,本文将对Kotlin中类的创建、属性、函数等方面做一个简单的介绍,也是自己学习后的一点心得

一、类

1、类的创建:
最基本的创建类和java中相同,修饰符+ 类名{}( 如果一个类没有类体,可以省略花括号
class Empty
class Empty{
}
2、构造函数:在 Kotlin 中的一个类可以有一个主构造函数和一个或多个次构造函数
主构造函数:

class Person constructor(firstName: String) {
}
如果主构造函数没有任何注解或者可见性修饰符,可以省略这个 constructor 关键字。
class Person(firstName: String) {
}
此时我们在创建对象时就可以直接初始化firstName:
var person = Person("Name")
此时实例化号person后,想通过person对象获取他的firstName属性,会发现掉不出他的属性,此时应将Person 的参数firName添加修饰符val/var,这两者的区别在之前已经区分过
class Person (var firstName : String){
}
var person = Person("Name")
        person.firstName = "B"
3.次构造函数:
如果类有一个主构造函数,每个次构造函数需要委托给主构造函数, 可以直接委托或者通过别的次构造函数间接委托。委托到同一个类的另一个构造函数用 this 关键字即可,现添加第二个构造函数:
constructor(name :String , age :Int):this(name){  //直接委托主构造函数
        this.age = age
    }
创建第二个对象:
 var personAge = Person("C",25)
        Log.e("personAge", personAge.firstName)
        Log.e("personAge",    personAge.age.toString())

下面我们创建第三个构造函数通过第二个间接委托主函数:
constructor(name :String , age :Int,sex :String):this(name,age){

    }
4、初始化代码块 
初始化块中的代码实际上会成为主构造函数的一部分。委托给主构造函数会作为次构造函数的第一条语句,因此所有初始化块中的代码都会在次构造函数体之前执行。即使该类没有主构造函数,这种委托仍会隐式发生,并且仍会执行初始化块

我们在上面的类中添加一个代码块:
 init {
        Log.e("=====","这是初始化代码快")
    }
    constructor(name :String , age :Int):this(name){
        Log.e("=====","这是次构造函数")
        this.age = age
    }
运行结果
主构造函数会调用代码块一次,次构造函数会把初始化代码块当成自己的第一条语句执行

5、类的继承
  • 父类要有open修饰,否则为final类型不可继承
  • kotlin中子类只可复写父类中开放的方法:用open修饰的方法
  • 复写的方法 必须带 override
  • 标记为 override 的成员本身是开放的,也就是说,它可以在子类中覆盖。如果你想禁止再次覆盖,使用 final 关键字:
6、覆盖方法
  • 覆盖无默认参数的方法:

现在在Person中添加一个方法:
  open  fun sum(x:Int,y:Int)= x + y
创建一个Child类继承Person
class Child(firstName: String) : Person(firstName) {

    override fun sum(x: Int, y: Int): Int {
        return super.sum(2*x, 2*y)
    }
}
创建child并调用sum方法:
var child = Child("Child")
       var result = child.sum(2,3)
        Log.e("=====", result.toString())//运行结果:10
  • 覆盖有默认参数的方法:是使用与基类型方法相同的默认参数值。 当覆盖一个带有默认参数值的方法时,必须从签名中省略默认参数值:
在person中再添加一个有默认参数的方法:
 open fun max(x :Int = 5,y:Int) = if (x > y) x else y
在child中的实现方法:
override fun max(x: Int , y: Int): Int { //省去默认值
        return super.max(x, y)
    }
调用:
child.max(y =10)//这个地方写 y = 10 之后再解释
7、覆盖冲突
在 Kotlin 中,实现继承由下述规则规定:如果一个类从它的直接超类继承相同成员的多个实现, 它必须覆盖这个成员并提供其自己的实现(也许用继承来的其中之一)。 为了表示采用从哪个超类型继承的实现,我们使用由尖括号中超类型名限定的  super ,如  super<Base>
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 {
    // 编译器要求覆盖 f():
    override fun f() {
        super<A>.f() // 调用 A.f()
        super<B>.f() // 调用 B.f()
  }
}
8、函数调用
  • 子类调用父类 使用super
class Child(firstName: String) : Person(firstName) {

    override fun sum(x: Int, y: Int): Int {
        return super.sum(2*x, 2*y)
    }
}
上述创建的子类Child 调用父类的sum方法 super.sum()
  • 子函数的内部类 调用 父类函数
现在我们在Child类中创建内部类Son

inner class Son{
        fun sum_son(): Int{
          return  [email protected](2,3)
        }
    }
调用sum_son方法:

var son = Child("A").Son()
        Log.e("=====", son.sum_son().toString())
输出结果为:02-02 13:24:32.128 13678-13678/com.example.administrator.kotlinpractise E/=====: 5

9、覆盖属性:

在超类中声明然后在派生类中重新声明的属性必须以 override 开头,并且它们必须具有兼容的类型。
你也可以用一个 var 属性覆盖一个 val 属性,但反之则不行
    open val boolean : Boolean = true
在child中
override val boolean: Boolean
        get() = super.boolean








猜你喜欢

转载自blog.csdn.net/alexwll/article/details/79236603