[Kotlin入门] 萌新篇(上)

看来我是很难改掉我话唠这个毛病了,不信你往下看。

先聊点别的?

不聊点别的,心里憋得慌啊,不知道怎么开头啊,我这人就是聊着聊着话就多起来,所以老哥们莫慌,坐下来喝杯茶听我慢慢掰扯;

主持人:“你今年多大了?”

我:“这是人家的秘密(TMD哪里跑个主持人出来?)。”

主持人:“哟哟哟,不好意思都来了,懂~那你嫁了么?哦不对,娶了么?”

我:“这是大型征婚节目现场?不是聊聊Kotlin的入门经验?”

主持人尴尬一笑,一副xxx(“欠揍”)的样子说到:“抱歉抱歉,职业习惯,职业习惯”,接着一本正经的说到“那你先简单的自我介绍一下您自己使用Kotlin的情况吧,另外,在场的大佬可以先离开了,毕竟这是入门级别的东西,不耐看。”

正经的说点啥

其实在17年之前就已经注意到了Kotlin,而且那时已经有一小撮人非常青睐Kotlin,并在某些社区中疯狂输出。当时是被Kotlin深深吸引的,因为在工作之初我是做跨平台开发的(用C#开发AndroidiOS,当时还叫mono,现在叫Xamarin),所以当了解到Kotlin能够应用在AndroidiOSWeb甚至Server领域时,心里为之一抖:“这B装的可以啊”,出于当时的好奇心以及被Java长久以来的诟病(繁琐、回调炼狱等)所折磨(大学学的Java,毕业工作用的C#,深感C#语言层面的优势),开始尝试Kotlin。

随着Kotlin的了解,深深的喜欢上了这门语言,当时Kotlin打着的旗号是与Java 100%互操作的,我胆子也比较大,便开始在一些场景使用Kotlin进行实际的应用场景开发,没记错的话当时的版本还是1.0x,紧接着5月份,Google宣布推荐Kotlin作为Android推荐开发语言,并且kt1.1版本随之发布。有了Google的大力支持,内心从此踏实,完全的拥入Kotlin的怀抱,至此便主要用Kotlin进行后续新业务开发和重构。

开发者们讨论语言时往往非常热闹,要是在群里说上一句“PHP是最好的语言”,哦不对,“Kotlin是Android开发的最好语言”,那就相当热闹了。也因此到现在,Kotlin可能还被一些人所质疑着。其实我也明白,大家心里有焦虑,有太多焦虑了,甚至焦虑隔壁的“Flutter大哥”跟“Aandroid老大哥”之间何去何从;不过焦虑始终是焦虑,我们干嘛要去焦虑今天大选的结果到底是“川建国”还是“懂王”呢,难道我的bug会因此少一点,所以与其焦虑不如先让自己Happy,不要每天自己都焦头烂额的,连自己的工作都应付不好的情况下,谈“焦虑”,会越来越“焦”,最后糊掉,被人收割;当然还要考虑实际的环境,有些想用但是又被条件制约,比如公司不采用,比如引进有困难,担忧对现有项目产生影响等种种问题;所以用还是不用,我们应该融入这个大圈子,站在自己所处的环境去考虑,我的建议就是如果你从事Android开发,并且也不会在短时间内改变这个现状也可以在项目中选择Kotlin,那就就不要拒绝使用Kotlin;

于我而言,使用Kotlin开发是幸福的,提高了我的工作效率,节省了开发时间,对于一名开发者来讲,这无疑是让人幸福的。

此时也许有人会犯嘀咕:“Kotlin不过是语法糖而已,哥不屑”,“Kotlin超多坑”,“Kotlin增大了编译时间”,“Kotlin太几把难学了”,“Kotlin的协程是什么鬼,有RxJava香么?”,“语言只是招式,内功才是王道”。。。。

这。。。你让我从何说起?是骡子是马,不要光听别人说,实践出真理,实操出贞操,一件事情值不值得去做,不能光凭别人怎么说。

来吧,Come on Kotlin,我们一起看看Kotlin到底是何方神圣。

说到这,我打开了Kotlin官方中文网站的学习文档,你们细品。

官方提供了非常好的学习资源,是我觉得学习Kotlin最好、最全的方式。官方文档地址奉上,小伙子,好好加油:看官方文档,靠谱儿;官方文档地址

毕竟Kotlin是一门完完整整的语言,要是三言两语就能说清楚搞明白,那铁定扯淡,我也只是蜻蜓点水。

Hello,World

类、变量、方法是一个程序组成的最为普遍的三个要素,所以我们先搞清楚这三个东西就基本能入门了,其他的后面再提升。

为了避免太过于复杂,我们先来看一段中规中矩的代码,尽量的与Java做对比;

///Study1.kt
//Study1.kt
class Study1 {//定义一个类

    //定义一个String类型的只读变量
    val content: String = "Hello,World."

    //定义一个私有String类型的变量
    private var name: String = "SuperLuo"

    //定义一个protect类型的变量
    protected var age:Int = 18

    //构造函数
    constructor(name: String):this(name,18)

    constructor(name:String,age:Int){
        this.name = name
        this.age = age
    }

    //定义一个方法
    fun sayHello() {
        println(this.name + "说道:\"" + content + "\"");
    }

    //定义一个带参数的方法,计算两者之和
    fun sum(a: Int, b: Int): Int {
        return a + b
    }

    //定义一个私有的方法打印当前时间
    private fun printCurrentDate(){
        println(Date().toString())
    }

}

麻雀虽小,五脏俱全,例子很简单,也是特意尽可能的用Java的形式来写的,毕竟大家对Java比较熟。

由于Kotlin跟Java几乎是100%互操作的,也就是两者可以相互调用,这道理也很简单,毕竟两者都是jvm语言,那最终两者都会编译成为jvm支持的class文件。我门先搞懂上面的东西,再说其他,欠的债,一步一步还。

变量

kotlin通过valvar申明变量,两者之间的区别是val赋值之后不能更改,而var变量可以。

Kotlin具备一个很好的特性->“类型推断”;也就是如果可以通过变量值推断出变量是什么类型,则定义变量的时候,类型可以省略:

var x = 5 // 自动推断出 `Int` 类型
x += 1

当然存在Kotlin无法正确推断类型的情况,此时需要定义时指明类型,val content: String = "Hello,World."

在这里不得不提的是:Kotlin中,万物皆对象;
Java中的基础类型都有与之对应的对象类型,比如int的对象类型为Integerlong的对象类型为Long;所以在Kotlin中不存在基础类型,只有对象类型(其中整形类型为Int而非Java中的Integer,其他一样),至于为什么这么设计官方上面有说明,但是我看的不太懂,最开始我也觉得有点别扭,但是到后来我觉得这样也没什么坏毛病,反而规则的统一对一些事情反而有利,尤其是借助扩展函数;

举个实际例子,比如程序中很多地方都需要处理点赞量的显示,当点赞数为0时显示成“点赞”,大于1万时显示成“x.xxw”,那么我们可以像如下方式实现:

//定义一个扩展方法处理展示规则
inline val Int.asFavorString{
    return when(this){
        0->"点赞"
            >10000 -> "${this.div(10000.0)}w"
        else -> this
    }
}

fun apply(){
    val textView:TextView ....
    //使用的时候,直接像1.asFavorString方法就可以调用了
    textView.text = 1.asFavorString
}

当然上面的例子不是很恰当,而且更多的是体现了扩展函数的作用,不过先简单意会一下吧。

函数

Kotlin使用fun关键字申明函数,类似如下规则 :

(可见修饰符,比如private,默认为public) fun 函数名(参数列表):返回值{}

	//带有两个参数的public方法
    fun sum(a: Int, b: Int): Int {
        return a + b
    }

    //无参数的私有方法
    //该函数的返回值为Unit,Unit是Kotlin中一个比较特殊的对象(并且还是用单例方式实现的),类似Java中void的概念,可以理解为无返回值类型,因此返回值为Unit的函数,返回值类型可以不写
    private fun printCurrentDate():Unit{
        println(Date().toString())
    }
    
    //省略Unit的写法:等同于上一个函数
    private fun printCurrentDate(){
        println(Date().toString())
    }
    

Kotlin类的定义也是使用class关键字,构造函数使用constructor申明。总体来讲跟Java差别不大。

使用

由于KotlinJava是可以共存的,也就是两者混合开发,那就存在互相调用的情况,两者互相调用时有些情况会有细微差别;

Java使用场景:

  @Test
  public void useStudyClassInJava() {
      //创建对象
      Study1 instance = new Study1("SuperLuo");
      //打印content变量值
      System.out.println("content=" + instance.getContent());
      //调用对象函数
      instance.sayHello();
      //调用对象带参数的函数
      int result = instance.sum(1, 2);
      System.out.println("1+2=" + result);
  }

Kotlin使用场景:

@Test
fun useStudyClassInKt(){
    //创建对象
    val instance = Study1("SuperLuo")
    //打印content变量值
    println("content=${instance.content}")
    //调用对象函数
    instance.sayHello()
    //调用对象带参数的函数
    val result = instance.sum(1,2)
    println("1+2=$result")
}

以上代码运行结果(两者结果相同):

content=Hello,World.
SuperLuo说道:"Hello,World."
1+2=3

从上面可以看到,两者不管从定义和使用上,只有细微的语法差别,所以上面的内容应该没有什么障碍;

不过眼尖的朋友可能还是看到了几个怪异的地方:
1、Kotlin创建对象时没有使用`new`关键字
2、Java代码访问对象的content变量时是使用的`getContent()`方法
至于第二个问题为什么会这样子,后面我会专门聊一下。

另外Kotlin的println函数其实就是调用的Java的System.out.println方法。
字符串拼接的时候,Kotlin我用了字符串模版的写法,其实比较等同于Java的String.format方法的效果

抽象类、接口

前面已经简单的了解了一下类、函数、变量,也进行了使用,类可以说是对程序来讲非常重要组成的元素,而跟类息息相关的另外东西是抽象类和接口;

抽象类
//与Java一样,使用abstrat定义抽象类
abstract class Person {
    var name: String
    val age: Int
    //抽象属性:可以定义抽象属性和抽象方法,而Java只有抽象方法;其实Kotlin的抽象属性最终也会转换成抽象方法,后面专门聊
    abstract val sex: String

    constructor(name: String) {
        this.name = name
        //age 是val变量,赋值之后就不能再修改了
        this.age = 18
    }
	
    //抽象方法
    abstract fun getAddress(): String

    fun printInfo() {
      	println("${name}今年${age}岁,性别${sex},住在${getAddress()}")
    }
}

//抽象类的子类,使用:进行继承
class Male(name: String) : Person(name){
    
    override val sex: String
        get() = "男"

    override fun getAddress(): String {
        return "火星"
    }
}

就不详细介绍了,可以先简单的看下注释。我们定义了一个抽象类,并且也定了一个子类,那么我们写个场景来使用这两个类;

@Test
fun testAbstract() {
    val me = Male("小罗")
    me.printInfo()
}

//执行结果:
小罗今年18岁,性别男,住在火星

与Java之间也没有特别大的差别,但是我们知道在Java开发中,我们可以创建匿名类来快速使用抽象类或者接口,这个大家应该就用的比较多了:

//创建了一个View.OnClickListener的匿名类对象
view.setOnClickListener(new View.OnClickListener(){
    @Override
    public void onClick(View v) {
    }
});

那在Kotlin中如何创建匿名类对象呢?上述代码在Kotlin中写法为:

view.setOnClickListener (object:View.OnClickListener{
    override fun onClick(v: View?) {

    }
})

//其实在Kotlin中上述写法还可以精简的写为,后面再具体说
view.setOnClickListener{
}

我们用匿名类的方式使用前面定义的Person类:

@Test
fun testAnonyClass(){
    val she = object:Person("Siri"){
        override val sex: String
            get() = "女"

        override fun getAddress(): String {
            return "太阳"
        }

    }
    she.printInfo()
}
//执行结果:
Siri今年18岁,性别女,住在太阳
接口

Java中,我们可以把接口当成一种特殊的抽象类,也就是接口所有的方法都是抽象的,但是在Kotlin中却不同,Kotlin中的接口既可以包含抽象方法的声明也可以包含实现。但是与抽象类不同的是,接口无法保存状态。

//定义枪的接口
interface Gun {
	//攻击力:不同的枪攻击力不同
    val power:Int
    //打印攻击力
    fun printPower(){
        println("攻击力$power")
    }
    //定义一个抽象的射击方法
    fun shoot()
}

class AK : Gun {
    override val power: Int = 800

    override fun shoot() {
        println("使用AK射击")
    }
}

//使用场景
@Test
fun testInterface() {
    val ak = AK()
    ak.printPower()
    ak.shoot()

	//匿名接口类实现
    val waterGun = object : Gun {
        override val power: Int
            get() = 0

        //重写了接口的默认实现逻辑
        override fun printPower() {
            println("水枪没有攻击力")
        }

        override fun shoot() {
            println("使用水枪攻击")
        }

    }
    waterGun.printPower()
    waterGun.shoot()
}

//运行结果:
攻击力800
使用AK射击
水枪没有攻击力
使用水枪攻击

接口跟抽象类的使用很相似;

告一段落

说实话写基础很没劲。。哈哈,所以先草草的结束,暂时到这里吧,算做个了解,对于一门编程语言的把握还是建议进行系统的学习,所以还是希望看官方文档进行学习最好。

前面聊了这么点东西,可能有朋友心里开发犯嘀咕了,难道Kotlin就这点东西?没意思!

我想说不是的,如果Kotlin仅此而已的话,完全没有存在的必要,否则它仅仅是Java的一个外国语版本罢了,反而恰恰相反;上面的代码场景很简单,其次我也有意将Kotlin的代码写的尽可能好理解,尽可能的跟用Java实现的方式一样,所以我们更难感受到Kotlin的魅力,说白了,Kotlin的“骚操作”还没有开始呢,因为怕整出太多与Java方式不同的东西,会让萌新们一时间难以消化。我们慢慢来,慢慢的体会Kotlin的骚操作吧。

后面我们主要围绕Kotlin的实际应用以及一些“骚”操作来讲吧,感受一下Kotlin的魅力,我也会更多的借助实际的使用场景来讲解。

Andme Github地址

欢迎入群交流:QQ276097690

更欢迎关注公众号

如果您有更多的建议或者交流,欢迎入群讨论,添加公众号更能第一时间了解最新内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值