Kotlin学习笔记之基础语法一

Kotlin学习笔记之基础语法一

编程行业已经混了4,5年了,接触了各种形形色色的编程语言,学习某一种语言的兴趣来源纯粹是因为某些网络大牛对它的各种吹捧,很少有去深入考虑过这门语言是否真的适合我。

话说回来,到我这个年纪再去学习什么新的语言似乎有点廉颇老亦的感觉,偶然接触到了kotlin这门语言,瞬间有种相见恨晚的激动,说不上为什么。终于下定决心在有生之年再接触一门语言,就它了。

一边学习,一边记录,点滴之间。

本人是Java的铁粉,也是我事业的主要方向,但接触过很多其他语言之后也发现了Java编程中的过程繁杂和无奈,比如一段期间接手IOS开发,一直非常羡慕OBJC 语言的一个牛逼特性 — 类型扩展。 简单点说就是能够对任何类,甚至系统类动态扩展新的方法或属性,而不是通过继承等方式。相信很多人也有过类似的经历和想法。

简单看过Kotlin的介绍及语法之后,更加坚定了我学习这门语言的决心,理由有以下几点:

  • 与Java完全兼容,因为Kotlin也是基于JVM的语言,在设计上完全兼容了Java的语言,Java的API,Java的类,因此我们可以在Kotlin中调用Java的任何功能,Java中也可以调用Kotlin中的API.
  • Kotlin实现了接口扩展技术,这也是让我非常激动的特性,从此可以让自己的代码简洁到不能再简洁。
  • Kotlin 还照搬了其他各种语言的长处,如Lamda表达式,switch超级扩展(不于限于case 常量),getter/setter (又一个照搬OBJC的语法),属性委托,语法上也模仿了ios新的开发语言swift等等,这些新特性往往是其他语言的精华所在,现在全部融入到了kotlin中,一语在手,天下我有的豪迈之气。
  • Kotlin 的空指针处理也是一大亮点,他将类型强制分为了可空各非空两种类型,极大的提高了系统设计的稳定性。
  • kotlin 竟然又将多重继承从C++中搬过来了!!虽然多重继承在设计上有很多隐患和缺陷,但他却真实的有其充分发挥的用武之地。很可惜的是Java并不支持,而要通过接口这种诡异的形式来变相实现多重继承。

说了这么多,其实远非这么多,最近熬夜吃小灶,希望能够快速系统的学习其所有语法和特性。
特此记录,以便回顾学习。


基础语法

一切学习,都与Java语法对比学习。

源码文件
Java的源码文件我们都知道必须要各类名相同,且不能包含游离的函数。
Kotlin 则允许文件名不需要与类名一致,同时文件中还可以包含任何单独的函数式声明,看起来就像C代码风格。
包名,以及导入导出
包名等基本规则与Java是一致的,直接参照Java规则就已经掌握了80了,还有一些微小的差别如下:
main 函数
Java的main函数不用多说了,需要声明一个类,然后声明一个final static main(){},
而在Kotlin中有所不同,声明main 函数不需要包含在一个类中,只需要在kt文件中即可,形式如下:
fun main(val args: Array){
    println("Hello World");
}
类声明
细节有很多,但基本格式没有多大变化,需要注意的有以下几点:
1. 默认为final 类形。如需要其可继承,可重写,需要声明open关键字
2. 方法默认为final 类型,不能重写,如需要,同样声明open关键字
3. 属性强制分为两类:变量和常量,关键字分别为var 和val.
4. 属性值强制分为两类:可能为空和不能为空,分别形如:Int? 和Int
5. 类型支持多重继承,类型C++样子。形如:class  Dog : Animal(), Singler(){/***TODO**/ }
6.  属性默认有getter/setter. 再也不用手动声明一堆的垃圾代码了。
7. 属性可以拥有委托模型,简单说就是可以通过委托随时知某个属性的变化,以及被访问的时机。假如你想知道某个属性在什么时候被修改了,这个特性将是你的救命药。(此种场景非常普遍,比如设置项的变更通知,控件属性值的变更通知等)
8. 属性赋值可以延迟到首次调用的时候,这个在加快类的初始化时将非常有用。比如有的变量我们不希望或者无法在对象构造的时候去赋值(可能缺少某些必要信息),此时我们便可以使用延时初始化。
9. 构造函数以及多重构造函数在声明以及写法上有所差异。
...

下边来直接用kotlin 声明一个类演示以上所提到的各种特性:

//1. main 函数声明格式。
fun main(args:Array){
    //2. 直接调用java类的方法,且末尾不需要;加上也没问题
    System.out.println("Hello Kotlin")
}

//这里信息量略大,类声明带open表示可以被继承,()声明相当于一个简化了的构造函数声明,类似Java中的public Animal(String name){}
//同时这里的name 前加了var 或者val 则表示name 也算做Animal 的一个属性,不需要再另行声明name属性了。
open class Animal(var name:String){

    var age:Int = 0 //声明一了个age属性,且为非空Int类型,此时在其他地方使用时则不能给age赋值为null.

    //函数声明前带open表示可以重写。String?表示参数可能为空值。
    open fun say(words: String?){

        //println是kotlin系统提交的简便api接口,实际就是简化的System.out.println(),这里的亮点是我们可以直接在字符串中引用变量的值:$name. 不再需要用+号连接一大堆内容了,非常方便。这里又是模仿了php的语法糖。
        println("Hello I am an Animal:$name");
    }

    //同样的可以加上权限限定public,同时如果有返回值则需要在:后跟返回值类型,模仿了objc语法。这里可以看到并没有写return, 在kotlin的世界中,代码块中的最后一句结果永远是此代码块的返回值,不需要写return.
    public fun doFinal():String{
        //do final. return String content.
        "Hello, this return a String,but not need to write return"
    }
}
//可以声明一个空类,什么都没有,实际可以通过扩展语法为其动态增加功能。
open class Empty

open interface Singer{}
//这里可以看到多重继承,同时也遵循子类的规则:必须重写构造函数。这个写法稍微有点复杂。
class Dog(name:String):Animal(name),Singer{

    override fun say(words :String){
        println("i override parent's say fun:$words")
    }
}

//属性延时初始化
//示例代码中可以用在Android工程中的真实代码,Application即为android中的应用程序类,经常性的我们需要保存一个全局的app对象,用于其他模块的context使用(未学android的可以选择性忽略)。一般情况下我们需要在onCreate()的时候为其赋值,但这里用了延时初始化的语法: by lazy{}
//by lazy{}意思就是说在第一次调用这个变量的时机才会去初始化执行lazy块的代码,并返回一个初始化结果,这里返回了this,即Application对象本身。此时application实例是肯定存在的,因此代码能够正常使用this. 这里省略了return,直接以this作为返回值赋给app属性。
class APP: Application(){
    val app:Application by lazy {this}
}

//kotlin的属性隐含的包含getter/setter.
class Property{
    var prop1:String by Delegate()

    var prop2:String
    get
    setter(value){
        println("prop2:修改了值为:$value")
        $prop2 = value
    }
}

//此类对象被委托接收prop1属性值get/set方法的代理监听,即prop1被访问或者被赋值时,Delegate中的方法就会被触发。
class Delegate{
        operator fun getValue(prop: Property, property: KProperty<*>): Int {
        println("get方法被调用")
        return 0
    }

    operator fun setValue(animal: Animal, property: KProperty<*>, i: Int) {
        println("set方法被调用")
    }
}

以上代码通过示例简单演示了kotlin中的一些特性,从使用上来说对于习惯了Java的同学可能有短期的不适应,比如经常习惯性的先写类型名再写变量名。但kotlin相对Java,其语法特性等表现手法已经有了质的提高,能够简化我们很多工作量以及代码数。所以非常值得一试!

函数声明

kotlin 支持函数声明默认参数,呐尼,这不是C语言的基本功能吗?默认参数可以干什么呢?简单来说以前Java为了实现不同参数的同一逻辑处理,要写N多同名函数,现在统统不用了!一个函数搞定。示例:

    //以下函数为File 对象增加了一个新的方法,并且携带两个默认参数值,使用时可以按需传递参数也可不传。
    public inline fun File.bufferedWriter(
                                charset: Charset = Charsets.UTF_8, 
                                bufferSize: Int = DEFAULT_BUFFER_SIZE): BufferedWriter{
                                //Do somthing.
    }

    //给字符串类型增加了一个新的方法findChar()。
    fun String.findChar(c: Char):Int{
        return this.indexOf(c)
    } 

    fun  rootFunction():String{
        "这是一个root 方法,不属于任何类,类似于C语言中的方法声明。可以用于任何地方直接调用。"
    }

用法就不用解释了,你可以传递其他参数值进去,也可以省略参数。再也不怕重载函数的各种坑了。
另外函数声明要注意几点:
1. 可以直接在kt即kotlin源码文件中声明函数,而不需要写在某个类范围中。这些函数将属于root方法,可以被任何地方使用(java 代码中除外),Java源码中是无法调用这些函数的。
2. 可以在kt源文件中为其他已有类型扩展新的方法,如上面示例,此时整个工程中的所有kotlin源文件中都是可见的,即可以在被扩展的类型的对象上调用此方法了。同样Java源码除外,无法在Java中调用这些扩展方法。
3. 每一个函数都有返回值,java void 返回类型对应 Unit, 可以省略。其他类型不可省略。

末完待续!

参考:
https://kotlinlang.org/docs/reference/classes.html http://blog.csdn.net/hp910315/article/details/50845465
http://kotlinlang.org/docs/reference/comparison-to-java.html

你可能感兴趣的:(Kotlin,编程语言,Kotlin,Java)