接口

在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中不能访问。这会导致什么??