IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Kotlin开发第一天,快速入门 -> 正文阅读

[移动开发]Kotlin开发第一天,快速入门

完整代码Gitee地址:kotlin-demo: Kotlin学习代码

第一天学习内容代码:Chapter1类

创建一个LearnKotlin.kt类

知识点1:日志输出

fun main() {
    //1、日志打印
    println("日志输出")
???????}  

点run执行结果

知识点2:变量声明 val、var

fun main() {
    //2、val声明一个不可变变量  对应java的final
    //var声明一个可变变量 好的代码习惯,优先使用val
    val a = 10
    val b = 37
???????}  

知识点3:定义函数、语法糖

fun main() {
    //3、定义函数
    val a = 10
    val b = 37
    println("methodName = " + methodName(a, b))
    //函数的语法糖写法
    fun methodName(param1: Int, param2: Int) = max(param1, param2)
    println("methodName = " + methodName(a, 20))
???????}  

//fun(function的简写)是定义函数的关键字
//fun后面的是函数名
//函数名后面紧跟着一对括号,里面可以声明该函数接收什么参数,参数的数量可以是任意多个
//参数括号后面的那部分是可选的,用于声明该函数会返回什么类型的数据
fun methodName(param1: Int, param2: Int): Int {
    //返回两个参数中更大的那个数
    return max(param1, param2)
}

打印日志结果为:?

知识点4:条件语句 if、where

????????Kotlin中的条件语句主要有两种实现方式:if和when。

? ? ? ? 如果你熟悉Java的话,应该知道Java中的switch语句并不怎么好用。首先,switch只能传入整型或短于整型的变量作为条件,JDK 1.7之后增加了对字符串变量的支持,但如果你的判断逻辑使用的并非是上述几种类型的变量,那么不好意思,switch并不适合你。其次,switch中的每个case条件都要在最后主动加上一个break,否则执行完当前case之后会依次执行下面的case,这一特性曾经导致过无数奇怪的bug,就是因为有人忘记添加break。

? ? ? ? 而Kotlin中的when语句不仅解决了上述痛点,还增加了许多更为强大的新特性,有时候它比if语句还要简单好用,现在我们就来学习一下吧

fun main() {
    //4、条件语句 if、where
    conditional()
???????}  

//4、条件语句
fun conditional() {
    //用if判断二个函数的较大值
    println("ifMethodName = " + ifMethodName(20, 50))

    //语法糖写法
    fun ifMethodName1(num1: Int, num2: Int) =
        if (num1 > num2) {
            num1
        } else {
            num2
        }

    //语法糖再精简
    fun ifMethodName(num1: Int, num2: Int) = if (num1 > num2) num1 else num2 * 2
    println("ifMethodName = " + ifMethodName(15, 35))

    //用where判断成绩,与Java相比不用写break,且是有返回值的可精简为
    fun whenStudent(name: String) =
        when (name) {
            "Peace" -> 60
            "Jay" -> 72
            "what" -> 80
            else -> 0
        }
    println("ifStudent = " + whenStudent("Jay"))

    //用where判断参数类型
    fun whenType(num: Number) =
        when (num) {
            is Int -> println("is Int")
            is Double -> println("is Double")
            is Long -> println("is Long")
            is Float -> println("is Float")
            is Short -> println("is Short")
            else -> println("else")
        }
    whenType(1234567890987654321)

    //如果我们不在when语句中传入参数的话,还可以这么写
    //举个例子,假设所有名字以Pea开头的人,他的分数都是90分,这种场景如果用带参数的when语句来写就无法实现
    fun whenStu(name: String) = when {
        name.startsWith("Pea") -> 90
        name == "Peace" -> 60
        name == "Jay" -> 72
        name == "what" -> 80
        else -> 0
    }
    println("whenStu = " + whenStu("Peace"))
}

//用if判断二个函数的较大值
fun ifMethodName(num1: Int, num2: Int): Int {
//    var value = 0
//    if (num1 > num2) {
//        value = num1
//    } else{
//        value = num2
//    }
    //if是有返回值的,可以简化为
    return if (num1 > num2) {
        num1
    } else {
        num2
    }
}

?打印日志结果为:?

知识点5:循环语句 for 、代码区间

????????Kotlin在for循环方面做了很大幅度的修改,Java中最常用的for-i循环在Kotlin中直接被舍弃了,而Java中另一种for-each循环则被Kotlin进行了大幅度的加强,变成了for-in循环,所以我们只需要学习for-in循环的用法就可以了

????????val value = 0..10,这种语法结构看上去挺奇怪的吧?但在Kotlin中,它是完全合法的。上述代码表示创建了一个0到10的区间,并且两端都是闭区间,这意味着0到10这两个端点都是包含在区间中的,用数学的方式表达出来就是[0, 10]。

????????Kotlin中可以使用until关键字来创建一个左闭右开的区间,使用step跳过区间内的元素,使用downTo遍历降序区间。

fun main() {
    //5、循环语句 for
    loopInfo()
???????}  

//5、循环语句 for
fun loopInfo() {
    //使用for-in遍历区间
    val value = 0..10
    for (i in value) {
        print(" $i")
    }

    //双端闭区间不如单端闭区间好用,相信你一定知道数组的下标都是从0开始的,
    //一个长度为10的数组,它的下标区间范围是0到9,因此左闭右开的区间在程序设计当中更加常用。
    //Kotlin中可以使用until关键字来创建一个左闭右开的区间
    //使用until替代..关键字,就不会打印10
    println(" ")
    val range = 0 until 10
    for (i in range) {
        print(" $i")
    }

    //如果想跳过其中的一些元素,可以使用step关键字
    //上述代码表示在遍历[0, 10)这个区间的时候,每次执行循环都会在区间范围内递增2,
    //相当于for-i循环中i = i + 2的效果
    println(" ")
    for (i in range step 2){
        print(" $i")
    }

    //前面的..和until关键字都要求区间的左端必须小于等于区间的右端,
    //也就是这两种关键字创建的都是一个升序的区间。
    //如果你想创建一个降序的区间,可以使用downTo关键字
    println(" ")
    for (i in 10 downTo 0){
        print(" $i")
    }
    println(" ")
}

?打印日志结果为:?

知识点6:面向对象

????????不同于面向过程的语言(比如C语言),面向对象的语言是可以创建类的。类就是对事物的一种封装,比如说人、汽车、房屋、书等任何事物,我们都可以将它封装一个类,类名通常是名词。而类中又可以拥有自己的字段和函数,字段表示该类所拥有的属性,比如说人可以有姓名和年龄,汽车可以有品牌和价格,这些就属于类中的字段,字段名通常也是名词。而函数则表示该类可以有哪些行为,比如说人可以吃饭和睡觉,汽车可以驾驶和保养等,函数名通常是动词。

fun main() {
    //6、面向对象
    objectView()
???????}  

//6、面向对象
fun objectView() {
    //拥有了3种方式来对StudentModel类进行实体化,
    //分别是通过不带参数的构造函数、通过带两个参数的构造函数、通过带4个参数的构造函数
    val student1 = StudentModel()
    val student2 = StudentModel("周润发",28)
    val student3 = StudentModel("111222",3,"周润发",28)

    //类中只有次构造函数,没有主构造函数写法
    val student = StudentModel1("333444",6,"刘德华",18)

}
创建StudentModel数据模型
/**
 * Created by: PeaceJay
 * Created date: 2021/10/25
 * Description: 学生信息模型
 */
//继承了PersonModel的姓名与年龄
//sno学号 grade年级 name姓名 age年龄
class StudentModel(sno: String, grade: Int, name: String, age: Int) : PersonModel(name, age) {

    //主构造函数没有函数体,如果我想在主构造函数中编写一些逻辑,该怎么办呢?
    //Kotlin给我们提供了一个init结构体
    init {
        println("sno=$sno, grade=$grade,name=$name,age$age")
    }

    //次构造函数是通过constructor关键字来定义的,通过this关键字调用了主构造函数
    //第一个次构造函数接收name和age参数,然后它又通过this关键字调用了主构造函数,并将sno和grade这两个参数赋值成初始值
    constructor(name: String, age: Int) : this("", 0, name, age) {

    }

    //第二个次构造函数不接收任何参数,它通过this关键字调用了我们刚才定义的第一个次构造函数,
    //并将name和age参数也赋值成初始值,由于第二个次构造函数间接调用了主构造函数,因此这仍然是合法的
    constructor() : this("", 0) {

    }

}
类中只有次构造函数,没有主构造函数写法
//首先Student类的后面没有显式地定义主构造函数,同时又因为定义了次构造函数,
//所以现在Student类是没有主构造函数的。那么既然没有主构造函数,
//继承Person类的时候也就不需要再加上括号了
class StudentModel1 : PersonModel {
    constructor(sno: String, grade: Int,name: String, age: Int) : super(name, age) {
        println("sno=$sno, grade=$grade,name=$name,age$age")
    }
}

?打印日志结果为:?

知识点7:接口、函数修饰符

????????Kotlin中的接口部分和Java几乎是完全一致的。接口是用于实现多态编程的重要组成部分。我们都知道,Java是单继承结构的语言,任何一个类最多只能继承一个父类,但是却可以实现任意多个接口,Kotlin也是如此。

????????我们可以在接口中定义一系列的抽象行为,然后由具体的类去实现。下面还是通过具体的代码来学习一下,首先创建一个Study接口,并在其中定义几个学习行为。

/**
 * Created by: PeaceJay
 * Created date: 2021/10/25
 * Description: 定义学生接口
 */
interface Study {
    //在Study接口中添加几个学习相关的函数
    fun readBooks()
    fun doHomeWork()

    //我们给doHomework()函数加上了函数体,并且在里面打印了一行日志。
    //如果接口中的一个函数拥有了函数体,这个函数体中的内容就是它的默认实现。
    //现在当一个类去实现Study接口时,只会强制要求实现readBooks()/doHomeWork()函数,
    //而newDoHomeWork()函数则可以自由选择实现或者不实现,不实现时就会自动使用默认的实现逻辑
    fun newDoHomeWork(){
        println("newDoHomeWork")
    }
}

接下来就可以让StudentBean类去实现Study接口了?

//Java中继承使用的关键字是extends,实现接口使用的关键字是implements,
//而Kotlin中统一使用冒号,中间用逗号进行分隔
//必须加var否则无法引用
class StudentBean(var name: String, age: Int) : PersonModel(name, age), Study {

    override fun readBooks() {
        println("$name is readBooks")
    }

    override fun doHomeWork() {
        println("$name is doHomeWork")
    }
}

??现在我们可以在main()函数中编写如下代码来调用这两个接口中的函数

fun main() {
    //7、接口
    interfaceView()
???????}  

//7、接口
//接口是用于实现多态编程的重要组成部分。我们都知道,Java是单继承结构的语言,
//任何一个类最多只能继承一个父类,但是却可以实现任意多个接口,Kotlin也是如此
fun interfaceView() {
    val student = StudentBean("刘德华",18)
    doStudy(student)
}

//演示一下多态编程的特性
fun doStudy(student: StudentBean) {
    student.readBooks()
    student.doHomeWork()
    student.newDoHomeWork()
}

?打印日志结果为:??

了解函数的可见性修饰符

????????Java中有public、private、protected和default(什么都不写)这4种函数可见性修饰符
Kotlin中也有4种,分别是public、private、protected和internal;
????????private:private修饰符在两种语言中的作用是一模一样的,都表示只对当前类内部可见
????????public:public修饰符的作用虽然也是一致的,表示对所有类都可见,但是在Kotlin中public修饰符是默认项,而在Java中default才是默认项;
????????protected:protected关键字在Java中表示对当前类、子类和同一包路径下的类可见,在Kotlin中则表示只对当前类和子类可见;
????????default:Kotlin抛弃了Java中的default可见性(同一包路径下的类可见),引入了一种新的可见性概念,只对同一模块中的类可见,使用的是internal修饰符。比如我们开发了一个模块给别人使用,但是有一些函数只允许在模块内部调用,不想暴露给外部,就可以将这些函数声明成internal;

知识点8:数据类(数据模型)

????????数据类通常占据着非常重要的角色,它们用于将服务器端或数据库中的数据映射到内存中,为编程逻辑提供数据模型的支持。或许你听说过MVC、MVP、MVVM之类的架构模式,不管是哪一种架构模式,其中的M指的就是数据类。

????????数据类通常需要重写equals()、hashCode()、toString()这几个方法。其中,equals()方法用于判断两个数据类是否相等。hashCode()方法作为equals()的配套方法,也需要一起重写,否则会导致HashMap、HashSet等hash相关的系统类无法正常工作。toString()方法用于提供更清晰的输入日志,否则一个数据类默认打印出来的就是一行内存地址。

????????这里我们新构建一个手机数据类,字段就简单一点,只有品牌和价格这两个字段。如果使用Java来实现这样一个数据类,代码就需要这样写:

/**
 * Created by: PeaceJay
 * Created date: 2021/10/25
 * Description:
 */
//Java版本写法
//数据类通常需要重写get()/set()、equals()、hashCode()、toString()这几个方法
public class Cellphone {
    private String brand;
    private double price;

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public Cellphone(String brand, double price) {
        this.brand = brand;
        this.price = price;
    }

    //toString()方法用于提供更清晰的输入日志,否则一个数据类默认打印出来的就是一行内存地址
    @NotNull
    @Override
    public String toString() {
        return "Cellphone{" +
                "brand='" + brand + '\'' +
                ", price=" + price +
                '}';
    }

    //equals()方法用于判断两个数据类是否相等
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Cellphone cellphone = (Cellphone) o;
        return Double.compare(cellphone.price, price) == 0 &&
                Objects.equals(brand, cellphone.brand);
    }

    //hashCode()方法作为equals()的配套方法,也需要一起重写,否则会导致HashMap、HashSet等hash相关的系统类无法正常工作
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    public int hashCode() {
        return Objects.hash(brand, price);
    }
}

Java的写法就显得比较复杂了,来试试Kotlin:

/**
 * Created by: PeaceJay
 * Created date: 2021/10/25
 * Description:
 */
//你没看错,只需要一行代码就可以实现了!
//神奇的地方就在于data这个关键字,当在一个类前面声明了data关键字时,
//就表明你希望这个类是一个数据类,Kotlin会根据主构造函数中的参数帮你将equals()、hashCode()、toString()等,
//固定且无实际逻辑意义的方法自动生成,从而大大减少了开发的工作量。
data class CellphoneKt(val brand: String, val price: Double) {
    init {
        println("brand=$brand" + "price=$price")
    }
}

????????只需要一行代码就可以实现了!就在于data这个关键字,当在一个类前面声明了data关键字时,就表明你希望这个类是一个数据类。

????????下面我们来测试一下这个数据类,在main()函数中编写如下代码:

fun main() {
    //8、数据类
    dataView()
???????}  

//8、数据类
fun dataView() {
    //在一个规范的系统架构中,数据类通常占据着非常重要的角色,
    //它们用于将服务器端或数据库中的数据映射到内存中,为编程逻辑提供数据模型的支持。
    //或许你听说过MVC、MVP、MVVM之类的架构模式,不管是哪一种架构模式,其中的M指的就是数据类

    //下面我们来测试一下这个数据类
    val cellphoneKt1 = CellphoneKt("小米11 12+256",4299.00)
    val cellphoneKt2 = CellphoneKt("红米K40 Pro+ 12+256",3699.00)
    val cellphoneKt3 = CellphoneKt("红米K40 Pro+ 12+256",3699.00)
    println(cellphoneKt1)
    println("cellphoneKt2 equals cellphoneKt3 = " + (cellphoneKt2 == cellphoneKt3))
}

?打印日志结果为:

知识点9:单例类

? ? ? ? 单例模式做为最常用、最基础的设计模式之一,它可以用于避免创建重复的对象,来看看Java版本:

/**
 * Created by: PeaceJay
 * Created date: 2021/10/25
 * Description: Java写法单例
 */
public class Singleton {
    //这段代码其实很好理解,首先为了禁止外部创建Singleton的实例,
    //我们需要用private关键字将Singleton的构造函数私有化,
    //然后给外部提供了一个getInstance()静态方法用于获取Singleton的实例。
    //在getInstance()方法中,我们判断如果当前缓存的Singleton实例为null,
    //就创建一个新的实例,否则直接返回缓存的实例即可,这就是单例模式的工作机制

    private static Singleton instance;

    private Singleton() {
    }

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

    public void SingletonText(){
        System.out.println("SingletonText");
    }

}

?调用单例类中的方法:

//调用单例类中的方法
Singleton singleton = new Singleton.getInstance();
singleton.SingletonText();

????????虽然Java中的单例实现并不复杂,但是Kotlin明显做得更好,它同样是将一些固定的、重复的逻辑实现隐藏了起来,只暴露给我们最简单方便的用法。在Kotlin中创建一个单例类的方式极其简单,只需要将class关键字改成object关键字即可。现在我们尝试创建一个Kotlin版的Singleton单例类:

/**
 * Created by: PeaceJay
 * Created date: 2021/10/25
 * Description:
 */
//在Kotlin中创建一个单例类的方式极其简单,只需要将class关键字改成object关键字即可
object SingletonKt {
    fun singletonText() {
        println("is singletonText")
    }
}

?在main()函数中编写如下代码:

fun main() {
    //9、单例类
    singletonView()
???????} 

//9、单例类
fun singletonView() {
    SingletonKt.singletonText()
}
 

?打印日志结果为:?

?学习参考:第一行代码——Android(第3版)第二章节

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-10-26 12:19:17  更:2021-10-26 12:19:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:00:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码