kotlin语法分析(一)

AS环境的配置

项目下的 build 文件

buildscript {

    ext.anko_version = '0.10.0-beta-2'//定义当前版本,方便后来引用
    ext.kotlin_version = '1.1.2'//定义当前版本,方便后来引用
    ext.support_version='25.0.3'
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.2'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }

}

allprojects {
    repositories {
        jcenter()
        maven { url "http://dl.bintray.com/kotlin/kotlin-dev" }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

model下的 build 文件

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
    compileSdkVersion 25
    buildToolsVersion "25.0.3"
    defaultConfig {
        applicationId "com.ydl.testmykotlin"
        minSdkVersion 19
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    kotlin {
        experimental {
            coroutines "enable"
        }
    }

    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
            exclude group: 'com.android.support', module: 'support-annotations'
        })
        compile 'com.android.support:appcompat-v7:25.3.1'
        testCompile 'junit:junit:4.12'
        compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
        compile "org.jetbrains.anko:anko-sdk25:$anko_version"
        compile "org.jetbrains.anko:anko-sdk25-coroutines:$anko_version"
        compile "org.jetbrains.anko:anko-appcompat-v7:$anko_version"
        compile "org.jetbrains.anko:anko-common:$anko_version"
        compile "com.android.support:recyclerview-v7:25.3.1"
    }
}

(1) kotlin的打印语句

println(“Hello , world”)
print(“Hello, World!”)

(2) java 的 打印语句

System.out.print(“Hello, World!”);
System.out.println(“Hello, World!”);

(3) variables

    像integer,float或者boolean等类型仍然存在,但是它们全部都会作为对象存在的。基本类型的名字和它们工作方式都是与Java非常相似的,但是有一些不同之处你可能需要考虑到:
    数字类型中不会自动转型。举个例子,你不能给 Double 变量分配一
个 Int 。必须要做一个明确的类型转换,可以使用众多的函数之一:

val i:Int=7  
val d: Double = i.toDouble()  

    字符(char),不能作为一个数字来处理,在需要时我们必须要把他们转换为一个数字

val c:Char='c'  
val i: Int = c.toInt()

    位运算也有一点不同。在Android中,我们经常在 flags 中使用“或”,所以我使用”and”和”or来举例:

// Kotlin  
val bitwiseOr = FLAG1 or FLAG2  
val bitwiseAnd = FLAG1 and FLAG2  
// Java  
int bitwiseOr = FLAG1 | FLAG2;  
int bitwiseAnd = FLAG1 & FLAG2;  

字面上可以写明具体的类型,也可以不写,我们可以通过编译器自动的推断出来.

val i = 12 // An Int  
val iHex = 0x0f // 一个十六  
val l = 3L // A Long  
val d = 3.5 // A Double  
val f = 3.5F // A Float  

一个String可以像数组一样的被迭代使用

val s = "Example"
val c = s[2] // 这是一个字符'a'
// 迭代String
val s = "Example"
for(c in s){
print(c)
}

(4) Null

var name : String? = null // 可以为null
var name : String =null // error
还记得java中的 非空判断吧~
if(string != null){
  int length = string.length();
}
现在可以这么写了
val length = string?.length
val length = string!!.length // NullPointerException if string == null

(5)变量

  变量可简单的分为 var(可变变量)和val(不可变量),这个和java中的final 很相似,一个不可以变得变量初始化以后就意味着不能在改变它的状态,如果你需要这个对象修改之后的版本,那就会重新的创建一个对象,这让编程编程变得更加具有健壮性和预估型,在java 中,大部分的对象是可变的,那就意味这任何访问它的代码都可以更改它的状态,从而会影响程序的其他的地方.
  不可变的对象可以称作为线程安全的,因为它们无法去改变,也不用改变控制,因为所有的线程访问的都是同一个对象, 所以在kotlin中,如果我们使用不可变性,我们的编码方式也要有一些改变,一个重要的概念就是尽可能的使用 val ,除了个别情(特别是在Android
中,有很多类我们是不会去直接调用构造函数的),大多数都是可以的.
在kotlin中,我们尽可能的不要在变量中去声明类的类型,它会自动的从后面的语句中推断出来,这样可让代码清晰快速的修改,

val s = "Example" // A String
val i = 23 // An Int
val actionBar = supportActionBar // An ActionBar in an Activity

如果我们需要使用更多的范型类型,则需要指定:

val a: Any = 23
val c: Context = activity

类,继承和函数

    kotlin遵守一个简单的结构和java还是有一点细微的差别,可以使用try.kotlinlang.org包下的
    怎么去定义一个类呢?
    如果你想定义一个类只需要使用class关键字就可以

class Actkotlin1 {

    //函数的使用
    fun add(a:Int,b : Int): Int{
        return a+b;
    }

}

    这是默认唯一的构造器,大多数情况只需要使用这个默认的构造器,就是在他后面加上它的参数,如果这个类中没有任何内容 大括号可以省略的`

class Actkotlin1 (var name:String ,var phone: String)

那么构造函数的函数体呢? 可以写在init快中:

class Actkotlin1 (var name:String ,var phone: String){
    init {

    }
}

    kotlin中 默认的所有的类都是继承自 Any 的 (和 java 的Object很相似),所有的类默认都是 不可继承的(final),我们只能继承 open 或者 是abstract

open class Animal (name: String)
class Person (name : String ,phone : String) : Animal(name)

    当我们只有单个构造器时,我们需要从父类继承下来的构造器中制定需要的参数,替换 java中的 super

继承

kotlin中所有的 类都有以恶搞通用的超类Any,这是一个没有父类型的类的超类

class Example 

Any 不是 java 中的object类,特别说明除了 equals(), hashcode(), toString()外,他不具有任何的成员函数
要声明一个显式的超类型,将冒号后面的类型放在类头中

open class Base(name : String)

class Childen (name : String) : Base(name)

如果类具有主构造函数,则可以使用主构造函数的参数初始化 基类型 .
如果类没有主构造函数,则每个辅助构造函数必须使用 super 关键字来初始化基类型.

class MyView : View{

    constructor (ctx : Context) : super(ctx)

    constructor (ctx : Context,attrs : AttributeSet) : super(ctx , attrs)
}

重载方法

open class Base {
    open fun v() {}
    fun nv() {}
}
class Derived() : Base() {
    override fun v() {}
}

Derived.v()需要覆盖(override)注释。 如果缺少(override)注释,编译器会抱错。 如果在一个函数上没有open注释,如在Base.nv()中,在子类中声明一个具有相同签名的方法是非法的,无论是否有覆盖(override)注释还是没有。 在final类(例如不使用open注释的类)中,则禁止覆盖成员。
标记为覆盖(override)的成员本身是打开的,即它可以在子类中被覆盖。 如果要禁止重新覆盖,请使用final关键字:

open class AnotherDerived() : Base() {
    final override fun v() {}
}

覆盖属性

覆盖属性的工作方式和覆盖方法类似,在超类上声明,在派生类上生命的属性,必须要用 override 来替代,必须具有兼容类型,每个声明的属性可被 具有初始化器或者 get,set方法覆盖

open class Foo {
    open val x: Int get { ... }
}

class Bar1 : Foo() {
    override val x: Int = ...
}

可以使用 var 属性覆盖 val 属性,反之也去可以,注意在主构造函数中使用override 关键字座位属性声明的一部分.

interface Foo {
    val count: Int
}

class Bar1(override val count: Int) : Foo

class Bar2 : Foo {
    override var count: Int = 0
}

覆盖规则

kotlin中实现继承有以下规则控制:如果类从其直接超类继承同一成员的多个实现,则它必须覆盖该成员并提供自己的实现. 要表示从其集成的实现的超类型,可在尖括号內使用超类型名称超级限定,例 super

open class A {
    open fun f() { print("A") }
    fun a() { print("a") }
}

interface B {
    fun f() { print("B") } // interface members are 'open' by default
    fun b() { print("b") }
}

class C() : A(), B {
    // The compiler requires f() to be overridden:
    override fun f() {
        super<A>.f() // call to A.f()
        super<B>.f() // call to B.f()
    }
}

从B继承A 是没有问题的,对于a(),b()也没有问题,因为C只继承每个函数的实现,但是对于f()有两个继承的实现,因此必须在C()中重写f(),并提供消除歧义的实现.

抽象类

一个类和其一些成员可以被声明为抽象,抽象函数在其类中没有实现,请不要使用open来注释 抽象类和函数.可以用抽象来继承非抽象的open 成员~

open class Base {
    open fun f() {}
}

abstract class Derived : Base() {
    override abstract fun f()
}

伴随对象

在kotlin中,类没有静态的概念(static),建议简单使用包级别的功能,如果需要编写一个可以调用的函数,而不需要一个类的实例,但需要去访问一个类的内部(例:工厂方法),可以将其作为一个对象声明来编写.

函数

     可以使用 fun 来定义:

fun onCreate(savedInstanceState: Bundle?) {

    }

如果没有指定返回值 默认的返回的是 Unit,与java中的 void很相似,但 Unit 是个真正得对象,当然咱们也可以去指定他的返回值

fun sum(a:Int,b:Int):Int=a+b

构造方法和函数参数

    kotlin 的参数和java 的有所不同,我么是先写参数的名字 再写它的类型

fun sum(a:Int,b:Int):Int{
    return a+b
}

    我们可以给参数指定一个默认值使得它们变得可选,这是非常有帮助的。这里有一
个例子,在Activity中创建了一个函数用来toast一段信息:

fun toast(message: String, length: Int = Toast.LENGTH_SHORT) {
Toast.makeText(this, message, length).show()
}

咱么在第二个参数中指定了一个默认值,这意味着你可以传或者不传,这样可以避免你需要的重载函数
toast(“hello world”)
toast(“hello world”,Toast.LENGTH_LONG)

fun niceToast(message: String,
tag: String = javaClass<MainActivity>().getSimpl
eName(),
length: Int = Toast.LENGTH_SHORT) {
Toast.makeText(this, "[$className] $message", length).show()
}

这个增加了一个参数 tag ,在java 中 总数的开销会很大.现在可以通过一下的方式调用:
toast(“Hello”)
toast(“Hello”, “MyTag”)
toast(“Hello”, “MyTag”, Toast.LENGTH_SHORT)
而且甚至还有其他的选择,通过参数名来调用,这表示你可以通过在值前 写明参数名来传入你想传的参数.
toast(message=”hello”,length=Toast.LENGTH_SHORT)
    温馨提示: 可以在模版中使用模版的表达式,在静态和变量的基础上 书写复杂的String,[ className] message”, 如果这个表达式 有点复杂可以去用大括号括起来”Your name is
${user.name}”。

属性

在kolin 中,属性和java 中的字段是相同的,但是更加的强大,属性做的事情是字段上加上get 和set方法,下面是java中的代码片段,

public class Person {
private String name;
public String getName() {
return name;
} 
public void setName(String name) {
this.name = name;
}
} .
..
Person person = new Person();
person.setName("name");
String name = person.getName();

在Kotlin中,只需要一个属性就可以了:

public class Person {
var name: String = ""
} .
..
val person = Person()
person.name = "name"
val name = person.name

如果没有任何的改变,那么属性会默认的使用getter和setter,当然它也可以修改为自定义的代码,并且不会修改存在的代码:

classs Person {
var name: String = ""
get() = field.toUpperCase()
set(value){
field = "Name: $value"
}
}

如果想要在getter和setter中访问这个属性自身的值,它需要 创建一个 backing field,可以使用这个 filed 预留字段来访问,它会被编译器找到正在使用的并自动创建,如果我们直接调用的属性,那么我们会直接调用 getter 和 setter 方法,而不是直接访问这个属性,backing field 只能在属性访问器內访问
当我们操作java代码的时候,kotlin将允许使用属性的语法去访问java中定义的getter 和setter所以在访问的时候不会有开销.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值