Kotlin高阶面向对象

高级部分

抽象类主要作为多个类的模板,而接口则定义了多个类应该遵守的规范

拓展

Kotlin的拓展是一个很独特的功能(Java中是不存在的)

基类拓展的方法,子类对象也是可以使用的。 拓展方法的this和成员方法的this一样是该对象的引用。

import java.util.*;
fun String.say() {
    println("Hello MCM!");
}
fun main(args: Array<String>) {
    var a : String = "Hello World!";
    a.say();
}

还可以在fun后添加 <T> 声明该函数是泛型函数

fun <T> ArrayList<T>.say() {
    for (i in this.indices) {
        println(this[i]);
        println("Hello World");
    }
}
fun main(args: Array<String>) {
    var list: ArrayList<String> = ArrayList<String>();
    list.add("A");
    list.add("B");
    list.add("C");
    list.say();
}
拓展的实现机制

Java是静态语言,一个类被定义完成无法动态添加和删除成员,除非重新编译该类

成员方法执行动态解析(由运行时类型决定)

拓展方法执行静态解析(由编译时类型决定)

open class BASE {
    open fun dynamic(){
        println("BASE_DY");
    }
}
class EXTEND : BASE(){
    override fun dynamic() {
        println("EXTEND_DY");
    }
}
fun BASE.static() {
    println("BASE_ST");
}
fun EXTEND.static() {
    println("EXTEND_ST");
}
fun main(args: Array<String>) {
    var base: BASE = EXTEND();
    base.dynamic();
    base.static();
}
拓展属性

拓展属性都是不能拥有幕后字段的,可以为其提供自定义的幕后字段(private),或者使用计算字段

var <T> ArrayList<T>.last_index
    get() = this.size - 1
    set(value) {}
fun main(args: Array<String>) {
    var arr: ArrayList<String> = ArrayList<String>()
    arr.add("Hello");
    arr.add("World");
    arr.add("!");
    println(arr.last_index); //Output: 2
}
以成员方式定义拓展

拓展的作用域只局限于这个类中,在类外时访问不到拓展的任何内容。

import java.util.*;
import kotlin.collections.ArrayList

class A 
class B {
    var a = A();
    fun A.say() {
        println("Hello World");
    }
    fun test() {
        a.say();
    }
}
fun main(args: Array<String>) {
    var b = B();
    b.test();
    // b.a.say();会报错,因为拓展的作用域只在B类中 
}

若在拓展的函数中使用的方法在 本类和被拓展的类中重名,参数列表也一样 返回值也一样的情况下,会优先使用被拓展类中的那个方法,除非使用 this@当前类名.方法 这种形式才能使用本类的方法。

之所以使用这种方式是因为默认的this是被拓展类对象的引用,通过 this@当前类名 这种方式可以临时将this作为当前类对象引用

class A {
    fun hello() {
        println("Hello A!");
    }
}
class B {
    fun hello() {
        println("Hello B!");
    }

    var a = A();
    fun A.say() {
        hello();
        this@B.hello();
    }
    fun test() {
        a.say();
    }
}
fun main(args: Array<String>) {
    var b = B();
    b.test();
}
带接收者的匿名函数

使用匿名函数为类拓展,该拓展函数所属的类也是该函数的接收者。

这种匿名函数也称作 “带接收者的匿名函数”

只要省略拓展函数的名即可

open class A
class B : A()
fun main(args: Array<String>) {
    var b = B();
    var hello = fun A.() {
        println("Hello");
    }
    b.hello();

    var say : A.() -> Unit;
    say = {println("Say")}
    b.say();
}

也可以使用Lambda表达式来拓展属性,这种函数类型为 拓展类名.函数类型

抽象

包含抽象成员的类只能被定义成抽象类,抽象类种可以没有抽象成员

抽象类不能被实例化,即使这个抽象类中没有抽象成员

与Java类似,Kotlin也允许抽象成员重写非抽象成员

open class BASE {
    open fun say(){
        println("Hello World");
    }
}
abstract class SUB: BASE(){
    override abstract fun say();
}
接口
  1. 修饰符可以是public | internal | private
  2. 一个接口可以有多个直接父接口,但接口只能继承接口,不能继承类

接口可以包含抽象方法也可包含非抽象方法,但接口中的属性没有幕后字段。

接口的属性要么声明为抽象属性,要么提供setter、getter方法

Kotlin接口成员可支持private和public两种访问权限

  1. 对于抽象方法、抽象属性必须使用public修饰,不加也默认public
  2. 对于不需要被实现类重写的成员,可以加private修饰,将这些成员在接口内访问。
接口的继承

接口完全支持多继承

虽然不能实例化,但可用来声明变量。必须引用到具体的实现类。

嵌套类与内部类

嵌套类(默认)

​ 嵌套类相当于静态内部类,由于Kotlin取消了static修饰符,因此都是非静态成员。因此嵌套类不可访问外部类的其他任何成员(只能访问其他嵌套类)

class PERSON {
    var x = 1;
    class HEAD {
        fun say() {
            println(x); //嵌套类(静态内部类),访问不到x
        }
    }
}
fun main(args: Array<String>) {
    var PH = PERSON.HEAD();
    PH.say();
}

嵌套类相当于外部类的静态成员,因此外部类的所有方法、属性、 初始化块都可以使用嵌套类来定义变量、创建对象。

子类无法使用父类的内部类

open class PERSON_STATIC {
    class HEAD {
        fun say() {
            println("STATIC CLASS");
        }
    }
}

class SUB: PERSON_STATIC()
fun main(args: Array<String>) {
    SUB.HEAD().say();
}
内部类

​ 内部类相当于非静态成员,内部可以访问到外部类的所有成员。但是要是想定义一个内部类成员,则必须要实例化一个外部类成员

class PERSON_STATIC {
    class HEAD {
        fun say() {
            println("STATIC CLASS");
        }
    }

}

class PERSON_INNER {
    inner class HEAD {
        fun say() {
            println("INNER CLASS");
        }
    }

}
fun main(args: Array<String>) {
    PERSON_STATIC.HEAD().say();
    PERSON_INNER().HEAD().say(); //必须实例化外部类之后才能实例化内部类
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值