写点什么

一文轻松掌握 Kotlin 接口与类

作者:Silently9527
  • 2024-09-18
    四川
  • 本文字数:2576 字

    阅读完需:约 8 分钟

一文轻松掌握Kotlin接口与类

程序员常用的 IDEA 插件:https://github.com/silently9527/Toolkit

微信公众号:贝塔学 Java

接口

Kotlin 接口定义依旧使用interface


interface Animal {    fun say()}
class Dog : Animal { override fun say() { println("汪汪...") }}
复制代码


  1. Kotlin 使用冒号来替代 Java 中的 extend,implements

  2. Kotlin 中 override 关键字是强制要求的,不能省略


Java 中的接口允许拥有默认实现,Kotlin 中也是同样支持的


interface Animal {    fun say() = println("Animal say:^%&**&&")}
复制代码


现在让我们假设同样存在定义了一个say的实现 Human,然后定义 Man 来实现这两个接口,默认 Man 会调用哪个 say 方法呢? 代码如下:


interface Human {    fun say() = println("Human say:Hello")}
class Man : Human, Animal {
}
复制代码


测试后的接口过是任何一个都不会被调用,编译阶段就会报错,Man 必须实现自己的 say,


class Man : Human, Animal {    override fun say() {        super<Animal>.say();        super<Human>.say();    }}
复制代码

open,final,abstract

Java 中只有显示的指定了 final,才能够控制类和方法不被重写,这就有可能导致脆弱基类的问题(对基类的方法重写导致行为不正常),所以 Kotlin 中方法默认都是 final, 如果需要支持重写需要使用手动使用 open 修饰


open class Man : Human, Animal {    override fun say() {        super<Animal>.say();        super<Human>.say();    }
open fun walkSpeed() { println("walk quick") }}
class OldMan : Man() { override fun say() { println("OldMan say:Hello, girl") }
override fun walkSpeed() { println("walk slow") }}
复制代码


其中Man需要被继承所有需要使用open修饰, walkSpeed需要被重写也需要使用open修饰; 接口中的方法和抽象类中的抽象方法默认是 open,无需在指定

可见性修饰符

Kotlin 与 Java 中的可见性修饰符一样,使用public, private, protected, 但是默认值不同, Kotlin 中默认值是 public

内部类

与 Java 中的内部类区别在于 Kotlin 中的内部类默认情况下是不能够访问外部类的实例, 这和 Java 中的静态内部类很相似


class Woman : Human {    override fun say() {        val info = Info("Taomm", 21)        println("Woman say: My name is ${info.name}, age is ${info.age}")    }
class Info(val name: String, val age: Int)}
复制代码


这里抽象出了个人信息的内部类 Info, 但是在这个 Info 中是没有办法访问 Woman 中的成员,如果需要访问时需要使用关键字inner


class Woman : Human {    val address: String = "Beijing";
override fun say() { val info = Info("Taomm", 21) println("Woman say: My name is ${info.name}, age is ${info.age}, address is ${info.getAddress()}") }

inner class Info(val name: String, val age: Int) { fun getAddress(): String = this@Woman.address }}
复制代码


访问外部类的时候需要通过this@Woman去操作

密封类

有时候需要把子类限制在父类中, 作为父类的内部类, 方便管理,这时候就需要使用关键字sealed修饰父类, sealed关键字隐含了这个类是 open, 所以无需在显式添加 open 关键字

构造方法

Kotlin 中构造方法使用关键字constructor, 如果需要调用重载的构造方法可以使用this(), 如果需要调用父类的构造方法可以使用supper()


class Person {    var name: String    var age: Int
constructor(_name: String) { this(_name, 20) }
constructor(_name: String, _age: Int) { name = _name age = _age }}
复制代码


在 Java 中经常会出现多个重载的构造方法, 与上面的两个构造方法类似, 在 Kotlin 中其实可以通过参数默认值以及参数命名替代掉,优化后的代码


class Person {    var name: String    var age: Int
constructor(_name: String, _age: Int = 20) { name = _name age = _age }}
fun main(args: Array<String>) { Person(_name = "Herman") //根据参数名字设置值}
复制代码


当我们的类只有一个构造函数的时候,可以继续简化,把成员属性和构造函数合并到一起


class Person (var name: String, var age: Int = 20) 
复制代码


类的初始化工作除了在构造函数中进行,还可以使用初始化语句块 init


class Person (var name: String, var age: Int = 20){    init {        //todo 初始化工作    }}
复制代码


如果你想要自己的类不能够被其他代码创建,需要把构造方法标记为 private


class Person private constructor(var name: String, var age: Int = 20) 
复制代码


  1. Kotlin 中创建对象的时候不需要使用 new 关键字,直接调用构造方法即可.

  2. 如果一个类没有任何构造方法,与 Java 一样 Kotlin 默认也会生成一个无参的构造方法

接口中声明属性

Kotlin 允许在接口中什么属性, 由于接口本身是不存储状态的,所以这个属性需要在子类来实现,具体是通过一个字段来存储,还是通过其他方式来获取就需要靠子类来实现


interface Human {    val email:String    val name:String        get() = email.substringBefore("@")}
复制代码


这个接口可以看到,接口中的属性依然可以拥有getter/setter, name给了默认的 getter, 那子类应该如何实现 email 属性呢?


  1. 直接通过一个变量来存储


class Man(override val email: String) : Human 
复制代码


  1. 提供 getter


class Man : Human{    override val email: String        get() = getEmailFromDb()
private fun getEmailFromDb(): String { TODO("database query") }}
复制代码

属性访问器(getter/setter)

Kotlin 中类的属性默认都提供了 getter/setter, 然后在使用的时候可以直接访问属性,无需像 Java 一样去调用 getter、setter 方法;


class Counter{    var count:Int=0        private set
fun inc(){ count++; }}
复制代码


这里定义了一个计数器,如果需要获取当前的计数可以直接访问属性Counter().count, 而 count 字段不能够被直接修改,只能调用inc方法,所以把这个 setter 设置成了private


原文链接: http://herman7z.site

最后(看完不点关注,你们想白嫖我吗)

文中或许会存在或多或少的不足、错误之处,有建议或者意见也非常欢迎大家在评论交流。


最后,写作不易,请不要白嫖我哟,希望朋友们可以点赞评论关注三连,因为这些就是我分享的全部动力来源🙏

发布于: 刚刚阅读数: 5
用户头像

Silently9527

关注

公众号:贝塔学JAVA 2018-05-09 加入

Simple Programmer, Make the complex simple

评论

发布
暂无评论
一文轻松掌握Kotlin接口与类_Java_Silently9527_InfoQ写作社区