安卓语言基础之Kotlin的面向对象编程

语言: CN / TW / HK

theme: smartblue

本文正在参加「金石计划 . 瓜分6万现金大奖」

前言

强大而灵活的RecyclerView Adapter——BRVAH(框架引入与BaseQuickAdapter使用篇) - 掘金 (juejin.cn)这篇文章中,我自定义了一个属性类,但其实当时我写的时候是恍惚了好一阵,因为习惯用Java语言开发安卓的我,一时不知道用Kotlin如何写类与其构造方法,异常尴尬,于是立刻翻出教程学习起来,然后才继续完成了这个Adapter的Demo,下面我们就来看看如何使用Kotlin完成面向对象编程吧!

image.png

正篇

类的写法

和Java一样的地方是都要用class关键字: ```Kotlin class Person { var name = "" var age = 0

fun profile() {
    println("name : $name, age : $age")
}

} 也是大括号里面写成员变量和成员方法,实例化也很简单:Kotlin val p = Person() ``` 只是没有new这个关键字,这是Kotlin的机制。

继承

Kotlin的继承不需要写extends关键字,而且Kotlin的继承机制也与Java不一样,在Kotlin中任何一个非抽象类默认都是不可继承的,原因与val关键字类似,因为类和变量一样,最好不可变,如果一个类允许被继承,它就无法预知子类会如何实现,从而导致出现一些未知风险,所以当一个类不是用来继承的,在Java中也应该用final声明,禁止其继承。

而Kotlin已经主动帮我们做好了,它默认所有非抽象类都不可被继承,而抽象类是不能直接实例化,需要子类继承才能创建实例,所有抽象类就是必须要被继承才行。

但如果我们想要让一个类可以被继承,其实只需要加上关键字open即可: ```Kotlin open class Person { var name = "" var age = 0

fun profile() {
    println("name : $name, age : $age")
}

} 然后在Kotlin中Java的继承关键字extends变成了“:”(冒号):Kotlin class Teacher : Person() { var num = 0 var className = "" } ``` 我们看到父类还加上了括号,这就是和下面要说的构造函数有关

构造函数

```Kotlin open class Person( val name : String, val age : Int ) { fun profile() { println("name : $name, age : $age") } }

class Teacher(var num : Int, var className : String, name: String, age: Int ) : Person(name, age) {

} ``` 我们可以看到和Java的构造函数不同,它不是写在类方法体的,而是像方法声明参数一样写在类名后的小括号内,所以父类继承时也就需要小括号,同时我们将子类Teacher后的这个小括号内容称作主构造函数,任何一个类只能有一个主构造函数,当然,有主构造函数,也会有次构造函数,这里先不过多阐述,后面有时间再更新到本文中。

有构造函数的类实例化: Kotlin val teacher = Teacher(25, "A", "SchoolPerson", 30)

接口

Kotlin的接口和Java的接口声明类似: Kotlin interface Teach { fun teach() fun work() } 继承后需要去实现接口的所有方法,继承不需要用Java的implements关键字,还是使用冒号,多个类时中间用逗号分开,接口不用名称后加小括号,因为它没有构造函数可调: ```Kotlin class Teacher(var num : Int, var className : String, name: String, age: Int ) : Person(name, age), Teach { override fun teach() { TODO("Not yet implemented") }

override fun work() {
    TODO("Not yet implemented")
}

} ``` 其中,override为Kotlin重写方法的关键字,和Java的@Override注解类似

此外,Kotlin也支持接口函数默认实现,即可以在接口中对函数实现,然后在实现接口时就不用强制实现该函数,自由选择是否实现该函数,不实习就调用默认实现方法: Kotlin interface Teach { fun teach() //默认实现 fun work() { println("Work!!") } } 继承后可以选择对已经默认的work方法实现或不实现:

image.png

默认实现去除继承中的实现方法不报错:

image.png

未实现继承后也不实现的话会报错:

image.png

这种使用接口的编程方式也叫面向接口编程,亦称多态。

数据类

数据类通常用于将服务器端或数据库的数据映射到内存中,为编程逻辑提供数据模型的支持,我们常说的MVC,MVP,MVVM这些架构模式的M即指代数据类

前言中那个图片其实就是想写数据类但当时还不知道Kotlin如何写就导致出现了个四不像的,但也勉强符合预期,后面会进行更正,那么数据类该如何写呢,我之所以写错就是因为Java中数据类实在不一样,在Java中我们通常要重写equals()、hashCode()和toString()方法,让这个类拥有数据类的功能: ```Java public class ModelDemo { String name; int age;

public ModelDemo(String name, int age) {
    this.name = name;
    this.age = age;
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof ModelDemo)) return false;
    ModelDemo modelDemo = (ModelDemo) o;
    return age == modelDemo.age && Objects.equals(name, modelDemo.name);
}

@Override
public int hashCode() {
    return Objects.hash(name, age);
}

@Override
public String toString() {
    return "ModelDemo{" +
            "name='" + name + ''' +
            ", age=" + age +
            '}';
}

} 而在Kotlin中,只要你加上关键字data就能自动帮你处理好这些,不需要做这些无用的工作:Kotlin data class ModelDemo(val name: String, val age: Int) 就这一句,简简单单。然后一样可以实现上面Java代码重写的方法的作用:Kotlin val modelDemo = ModelDemo("Name", 18) val modelDemo1 = ModelDemo("Name", 18) println(modelDemo) println(modelDemo == modelDemo1) ```

image.png

单例类

首先我们了解一下单例模式:

单例模式,最常用、最基础的设计模式之一,可用于避免创建重复对象,在全局最多只能拥有一个实例。

单例模式的写法很多,我们这边先看一下Java的一种常见写法: ```Java public class SingleDemo {

private static SingleDemo instance;

public SingleDemo() {}

public synchronized static SingleDemo getInstance() {
    if (instance == null) {
        instance = new SingleDemo();
    }
    return instance;
}

public void singleDemoTest() { System.out.println("singleDemoTest is called"); } } 调用:Java SingleDemo singleDemo = SingleDemo.getInstance(); singleDemo.singleDemoTest(); Java中看起来实现单例也不难,但当我看到Kotlin中时,真的笑了:Kotlin object SingleDemo { } 对,这就是Koltin版的单例,如果再加上Java中实现的方法:Kotlin object SingleDemo { fun singleDemoTest() { println("singleDemoTest is called") } } 调用看起来像在使用Java静态方法的调用,其实是Kotlin已经帮我们自动创建好了SingleDemo的实例,且会保证全局只存在一个SingleDemo实例:Koltin SingleDemo.singleDemoTest() ``` 只能说不愧是晚出来的语言,优势真明显,只需要把class关键字换成object,一个单例简简单单完成创建。

总结

本文将Kotlin的面向对象编程介绍了一遍,真的感受到了Kotlin的方便与优势,感谢大家的阅读!