接口

在kotlin中,也是使用interface来定义接口的。
接口中,可以定义属性和方法,方法可以实现,也可以不实现。但是他们都是默认为open的,也就是可以被继承和重写的。

  • 属性不能赋值,而且实现了这个接口的方法必须重写该属性,添加上get,set方法
  • 未实现的方法在被之后的类实现时,必须把这个方法也同时实现了。
  • 实现的方法(即带方法体的方法)可以不重写,而是直接使用。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    fun main(){
    B().showA()
    B().showB()
    }
    interface A{
    val sb:String
    fun showA(){
    println(123)
    }
    fun showB(){
    println("234")
    }
    }
    class B(): A {
    override val sb: String
    get() = sb
    }
    接口的使用还有一个问题:
    当两个接口,A,B都实现了showC的方法,而且都带有方法体。问:D类实现了A,B接口。那么D中使用showC会调用谁的方法?
    答:任何一个都不会,而是会编译报错
    即,如果同样的继承成员有不止一个实现,必须提供一个显式实现。
    Kotlin编译器强制要求你提供自己重写的方法:
    1
    2
    3
    4
    5
    6
    class C{
    override fun showC(){
    super<A>.showC()
    super<B>.showC()
    }
    }
    在kotlin中,他也可以使用super的关键字,但是需要选定基类,也就是super<>的尖括号中,需要填写基类。

控制继承的修饰符

修饰符 相关成员 评注
final 不能被重写 类中成员默认使用
open 可以被重写 需要明确的表明,且open的属性会被继承
abstract 必须被重写 只能在抽象类中使用,抽象成员不能有实现
override 重写父亲或接口中的成员 如果没有使用final表明,重写的方法默认是开放的

可见性修饰符

修饰符 类成员 顶层声明
public(默认) 所有地方可见 所有地方可见
internal 模块中可见 模块中可见
protected 子类中可见
private 类中可见 文件中可见

对于kotlin和java的区别:

  1. kotlin中没有默认类,或者说它默认就是public所有地方可见。
  2. internal是新增的修饰符,他表示在一个模块中可见,这个模块可以是指一个idea项目,eclipse项目,maven,ant项目。也就是同一个项目中可见
  3. protected对于java而言是同一个包内可见,而kotlin中化简为只在子类中可见。

然后在kotlin中,不允许可见度高的去调用可见度低的方法,如public不能调用internal,以此类推,保持一致。同样的外部类也不能看见内部类,如扩展函数是无法看到内部的protected,private方法的,保持了类的封闭性。

深入

在jvm编译过程中,kotlin被编译为字节码文件时,public,protected,private被编译成java字节码时会被保留,他们也保持了同样的可见性。例外:private会被编译成类包私有声明,因为在java中,不能把类声明为private。

internal会被编译成public。

提出疑问?
因为kotlin在编译为字节码后,和java的交互中,会有一些你在java中能访问,但是在kotlin中不能访问的内容,如:protected,在java的同一个包下能访问,但是kotlin中不能访问。这会导致什么??