return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public String toString() {
return “User{” +
“name='” + name + ‘’’ +
“, pwd='” + pwd + ‘’’ +
‘}’;
}
}
分析:实现同一个功能,从代码量来说,Koltin
比Java
少了很多行代码,比起更简洁。
1.3.2、修改数据类属性
例:修改User
类的name
属性
Kotlin版:
Koltin
要修改数据类的属性,若属性使用val
修饰,则只能使用其独有的copy()
函数。其作用就是:修改部分属性,但是保持其他不变,若用var
修饰,也可以用Setter()
函数修改,这一点和Java
一样
val mUser = User(“kotlin”,“123456”)
println(mUser)
mUser.name = “first new kotlin”
println(mUser)
val mNewUser = mUser.copy(name = “second new Kotlin”)
println(mNewUser)
输出结果为:
User(name=kotlin, pwd=123456)
User(name=first new kotlin, pwd=123456)
User(name=second new Kotlin, pwd=123456)
Java版:
User mUser = new User(“Java”,“123456”);
System.out.println(mUser);
mUser.setName(“new Java”);
System.out.println(mUser);
输出结果为:
User{name=‘Java’, pwd=‘123456’}
User{name=‘new Java’, pwd=‘123456’}
1.4、解构声明
- 在前面讲到,
Kotlin
中定义一个数据类,则系统会默认自动根据参数的个数生成component1() … componentN()
函数。其…,componentN()
函数就是用于解构声明的
val mUser = User(“kotlin”,“123456”)
val (name,pwd) = mUser
println(“name = KaTeX parse error: Undefined control sequence: \tpwd at position 5: name\̲t̲p̲w̲d̲ = pwd”)
输出结果为:
name = kotlin pwd = 123456
1.5、系统标准库中的标准数据类
- 标准库提供了 Pair 和 Triple。尽管在很多情况下命名数据类是更好的设计选择, 因为它们通过为属性提供有意义的名称使代码更具可读性。
- 其实这两个类的源码部分不多,故而贴出这个类的源代码来分析分析
1.5.1、源码分析
@file:kotlin.jvm.JvmName(“TuplesKt”)
package kotlin
// 这里去掉了源码中的注释
public data class Pair<out A, out B>(
public val first: A,
public val second: B) : Serializable {
// toString()方法
public override fun toString(): String = “(
f
i
r
s
t
,
first,
first, second)”
}
// 转换
public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)
// 转换成List集合
public fun Pair<T, T>.toList(): List = listOf(first, second)
// 这里去掉了源码中的注释
public data class Triple<out A, out B, out C>(
public val first: A,
public val second: B,
public val third: C ) : Serializable {
// toString()方法
public override fun toString(): String = “(
f
i
r
s
t
,
first,
first, second, $third)”
}
// 转换成List集合
public fun Triple<T, T, T>.toList(): List = listOf(first, second, third)
分析:从上面的源码可以看出,标准库中提供了两个标准的数据类,Pair类
以及Triple类
.其中:
- 两个类中都实现了
toList()
方法以及toString()
方法。to()
方法乃Pair类
特有,作用是参数转换Pair类
需要传递两个参数,Triple类
需要传递三个参数。
1.5.2、用法
val pair = Pair(1,2) // 实例
val triple = Triple(1,2,3) // 实例
println(“KaTeX parse error: Undefined control sequence: \t at position 6: pair \̲t̲ triple”) // 打印:即调用了各自的toString()方法
println(pair.toList()) // 转换成List集合
println(triple.toList()) // 转换成List集合
println(pair.to(3)) // Pair类特有: 其作用是把参数Pair类中的第二个参数替换
输出结果为:
(1, 2) (1, 2, 3)
[1, 2]
[1, 2, 3]
((1, 2), 3)
二、密封类
密封类是用来表示受限的类继承结构
2.1、什么是受限的类继承结构
- 所谓受限的类继承结构,即当类中的一个值只能是有限的几种类型,而不能是其他的任何类型。
- 这种受限的类继承结构从某种意义上讲,它相当于是枚举类的扩展。但是,我们知道
Kotlin
的枚举类中的枚举常量是受限的,因为每一个枚举常量只能存在一个实例。- 但是其和枚举类不同的地方在于,密封类的一个子类可以有可包含状态的多个实例。
- 也可以说成,密封类是包含了一组受限的类集合,因为里面的类都是继承自这个密封类的。但是其和其他继承类(
open
)的区别在,密封类可以不被此文件外被继承,有效保护代码。但是,其密封类的子类的扩展是是可以在程序中任何位置的,即可以不在同一文件下。
2.2、关键字
定义密封类的关键字:
sealed
声明格式
sealed class SealedExpr()
PS:密封类是不能被实例化的
即
val mSealedExpr = SealedExpr() // 这段代码是错误的,编译器直接会报错不能编译通过。
既然密封类
是不能实例化,那么我们要怎么使用,或者说它的作用是什么呢?
2.3、作用及用法
2.3.1、作用
用来表示受限的类继承结构。
例:
sealed class SealedExpr{
data class Person(val num1 : Int, val num2 : Int) : SealedExpr()
object Add : SealedExpr() // 单例模式
object Minus : SealedExpr() // 单例模式
}
// 其子类可以定在密封类外部,但是必须在同一文件中。v1.1
之前只能定义在密封类内部
object NotANumber : SealedExpr()
分析:即所定义的子类都必须继承于密封类,表示一组受限的类
2.3.2、和普通继承类的区别
- 普通的继承类使用
open
关键字定义,在项目中的类都可继承至该类。- 而密封类的子类必须是在密封类的内部或必须存在于密封类的同一文件。这一点就是上面提到的有效的代码保护。
2.3.3、和枚举类的区别
- 枚举类的中的每一个枚举常量都只能存在一个实例。而密封类的子类可以存在多个实例。
例:
val mPerson1 = SealedExpr.Person(“name1”,22)
println(mPerson1)
val mPerson2 = SealedExpr.Person(“name2”,23)
println(mPerson2)
println(mPerson1.hashCode())
println(mPerson2.hashCode())
输出结果为:
Person(name=name1, age=22)
Person(name=name2, age=23)
-1052833328
-1052833296
2.3.4、子类的类扩展实例
例:
// 其存在于SealedClassDemo.kt文件中
sealed class SealedExpr{
data class Person(val name : String, val age : Int) : SealedExpr()
object Add : SealedExpr()
companion object Minus : SealedExpr()
}
object NotANumber : SealedExpr()
// 其存在TestSealedDemo.kt文件中
fun SealedExpr.Add.add(num1 : T, num2 : T) : Int{
return 100
}
fun main(args: Array) {
println(SealedExpr.Add.add(1,2))
}
输出结果为:
100
说明:上面的扩展功能没有任何的意义,只是为了给大家展示密封类子类的扩展不局限与密封类同文件这一个功能而已
3.5、使用密封类的好处
- 有效的保护代码
- 在使用
when
表达式 的时候,如果能够验证语句覆盖了所有情况,就不需要为该语句再添加一个else
子句了。
例:
sealed class SealedExpr{
data class Person(val name : String, val age : Int) : SealedExpr()
object Add : SealedExpr()
companion object Minus : SealedExpr()
}
object NotANumber : SealedExpr()
fun eval(expr: SealedExpr) = when(expr){
is SealedExpr.Add -> println(“is Add”)
is SealedExpr.Minus -> println(“is Minus”)
is SealedExpr.Person -> println(SealedExpr.Person(“Koltin”,22))
NotANumber -> Double.NaN
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
尾声
评论里面有些同学有疑问关于如何学习material design控件,我的建议是去GitHub搜,有很多同行给的例子,这些栗子足够入门。
有朋友说要是动真格的话,需要NDK以及JVM等的知识,首现**NDK并不是神秘的东西,**你跟着官方的步骤走一遍就知道什么回事了,无非就是一些代码格式以及原生/JAVA内存交互,进阶一点的有原生/JAVA线程交互,线程交互确实有点蛋疼,但平常避免用就好了,再说对于初学者来说关心NDK干嘛,据鄙人以前的经历,只在音视频通信和一个嵌入式信号处理(离线)的两个项目中用过,嵌入式信号处理是JAVA->NDK->.SO->MATLAB这样调用的我原来MATLAB的代码,其他的大多就用在游戏上了吧,一般的互联网公司会有人给你公司的SO包的。
至于JVM,该掌握的那部分,相信我,你会掌握的,不该你掌握的,有那些专门研究JVM的人来做,不如省省心有空看看计算机系统,编译原理。
一句话,平常多写多练,这是最基本的程序员的素质,尽量挤时间,读理论基础书籍,JVM不是未来30年唯一的虚拟机,JAVA也不一定再风靡未来30年工业界,其他的系统和语言也会雨后春笋冒出来,但你理论扎实会让你很快理解学会一个语言或者框架,你平常写的多会让你很快熟练的将新学的东西应用到实际中。
初学者,一句话,多练。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
该你掌握的,有那些专门研究JVM的人来做,不如省省心有空看看计算机系统,编译原理。**
一句话,平常多写多练,这是最基本的程序员的素质,尽量挤时间,读理论基础书籍,JVM不是未来30年唯一的虚拟机,JAVA也不一定再风靡未来30年工业界,其他的系统和语言也会雨后春笋冒出来,但你理论扎实会让你很快理解学会一个语言或者框架,你平常写的多会让你很快熟练的将新学的东西应用到实际中。
初学者,一句话,多练。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!