Kotlin-改良的Java(一)

Kotlin-改良的java(一)

20天打卡计划 day01

Kotlin-改良的Java

​ 2010年,创造了pycharm和IDEA的大名鼎鼎的语言构建开发工具的JetBrains产生了改良Java这门主流编程语言的想法,设计之初的第一个问题就是兼容数百万行的Java代码库,这个背景也决定了Kotlin的核心目标——为Java程序员提供一门更好的编程语言(better Java—更好的Java)。Kotlin一直在兼容Java语言,这比其他运行在jvm上的语言走得更远,尤其从命名来看,Kotlin也在严格遵循Java的传统。(Java的名字来自印尼爪洼岛的英文,而kotlin是俄罗斯圣彼得堡附近的一座岛屿)

一些改良:

  • 可以直接用引入的object来直接声明一个单例(单例对象的类只能允许一个实例存在),对比Java:
// 懒汉式单例
public class Singleton {
 
    // 指向自己实例的私有静态引用
    //保证每次实例化对象拿到的都是这个类
    private static Singleton singleton;
 
    // 私有的构造方法
    private Singleton(){}
 
    // 以自己实例为返回值的静态的公有方法,静态工厂方法
    public static Singleton getSingleton(){
        // 被动创建,在真正需要使用时才去创建
        if (singleton == null) {
            singleton = new Singleton2();
        }
        return singleton;
    }
}
  • 引入了一些Java中没有的特殊类,Data Classes(数据类) ps:在java中我们创建一个数据类POJO需要大量的代码来实现get和set方法,心累。

  • 其他的俺也没学到,之后再说、、

Kotlin能做什么:

  • 首先作为Android官方支持的语言,Kotlin依赖于Google提供的扩展库,在Android开发中混的如鱼得水。
  • 服务器端开发,spring5已经增加了对kotlin的支持,无敌
  • 前端开发(没想到吧!我也没想到,哈哈哈)
  • 原生环境开发,Kotlin Native项目让Kotlin离开JVM独立发展,现在还处于项目的初期

Kotlin基础语法:

类型声明:

val a : String = "hello world";

与Java相反,kotlin的类型名放在变量名的后面,为什么采用这种风格,我们来对比一下Java

String a = "hello world";

与Java对比,第一是变量类型的位置,kotlin支持省略类型的声明,也就是可以写成下面这样,系统会自动推导出变量的类型,Kotlin是静态语言,但是通过增强的类型推导,来改善静态语言需要大量的声明类型这一情况。

val a = "hello world";

var和val:简单来说,val就是加了final修饰的var,引用不可变

高阶函数:

​ 这里我们要了解一下什么叫做函数式语言,在函数式语言中,函数是一等公民,主要成分是函数,可以把函数作为参数(接受一个过程(函数)为参数),结果也可以是函数(返回一个过程),这样的函数叫做高阶函数,高阶函数是一种更加高级的抽象形式,极大得增强了语言得表达能力。

​ Kotlin不是函数式语言,但是它天然支持部分函数特性(java8新特性也已经支持部分函数式特性):

fun foo(x:Int){
    //函数中定义函数
	fun double(y:Int) : Int{
		return y * 2
	}
	println(double(x))
}

举个栗子说一说函数式的牛逼之处:

假设我们要做一个统计用户信息的应用,刚开始我们的信息只有很少一部分,直接匹配名字就可以得到:


data class User(
        val name : String,
        val id : Int,
        val gender : String,
		val age : Int)

class App{
    fun findUser(users : List<User>): List<User>{
        val res = mutableListOf<User>()
        for (user in users){
            if(user.name == "汪涵"){
                res.add(user)
            }
        }
        return res;
    }
}

后来我们要叫汪涵的人多了,这个时候我们可以通过在if语句中加限定条件,比如年龄性别等,慢慢越加越多,代码的业务逻辑耦合也越来越高,怎么解决这个办法呢?

把所有的逻辑筛选 -行为- 抽象成一个 -参数- 传入findUser中

class test{
    fun isUser(user : User) : Boolean{
        return user.name == "汪涵" && user.gender == "男" && user.id == 1;
    }
}

函数我们有了,现在解决第二个问题怎么把函数作为参数,也就是怎么传,传什么的问题:

1.解决函数传递的类型问题(传什么):

函数作为参数传递,也需要具备具体的参数信息。

在Kotlin中函数类型(函数作为参数传递的类型,类似整型作为形参的int)的格式为:

(Int) -> Unit //Unit目前当作void,但是作为返回类型必须显式声明
/**
 * 通过->来传递参数,左边是参数类型,右边是返回值类型
 * 必须用一个括号来包裹参数类型
 * 返回值类型即使是Unit,也必须显示声明
 * 空值传参:() -> Unit
 * 多值传参:(String, Int) -> Unit
 * 为声明参数指定名字:(name: String, id: Int) -> Unit
 * 若某些情况id可空:(name: String, id: Int?) -> Unit
 * 若函数类型的变量可选:((name: String, id: Int?) -> Unit)?
 * 高阶函数还支持返回另外一个函数:
 *    对比 (Int) -> ((Int) -> Unit)
 *         (Int) -> Int -> Unit
 *        ((Int) -> Int) -> Uint
 */

明确了这些之后,传它!

class App{
    fun findUser(users : List<User>,
                testone : (User) -> Boolean
                ): List<User>{
        val res = mutableListOf<User>()
        for (user in users){
            if(testone(user)){
                res.add(user)
            }
        }
        return res;
    }
}

2.解决函数传递怎么传的问题

直接上代码吧:

App.findUser(Users,test :: isUser)

在c++中有命名空间的概念,使用::来调用某个类下的方法来获得方法或成员的引用,Kotlin中也可以用::来拿到类的属性或方法的引用。

和.的不同是,获取引用而不是调用(拿到但不用)。

今天结束啦啦啦啦,明天学习高阶函数的结尾和Lambda

你可能感兴趣的:(Kotlin,java,android,kotlin,jvm,javascript)