主构造器与次构造器
次构造器的写法
class LessonViewHolder : BaseViewHolder {
//次构造器 internal为可见性修饰符
internal constructor(itemView: View):super(itemView)
}
主构造器写法
class LessonViewHolder internal constructor(itemView: View) : BaseViewHolder(itemView) {
}
User类的主构造器与次构造器
次构造器
package com.example.app.entity
class User {
//kotlin中默认有get set方法
var username: String? = null
// ?表示可以赋值为null
var password: String? = null
var code: String? = null
//空构造函数
constructor() {
}
//带参数的构造函数
constructor(username: String?, password: String?, code: String?) {
this.username = username
this.password = password
this.code = code
}
}
主构造器
package com.example.app.entity
class User constructor() {
//kotlin中默认有get set方法
var username: String? = null
// ?表示可以赋值为null
var password: String? = null
var code: String? = null
//带参数的构造函数 : this() 调用无参主构造器
constructor(username: String?, password: String?, code: String?) : this() {
this.username = username
this.password = password
this.code = code
}
}
写法进一步优化
优化前:
class Lesson constructor(date: String?, content: String?, state: State?) {
var date: String? = null
var content: String? = null
var state: State? = null
init {
this.date = date
this.content = content
this.state = state
}
}
优化后:
class Lesson constructor(var date: String?, var content: String?, var state: State?) {
}
注意:主构造器上的参数只有在init初始化里面能访问,其他方法里不能访问
如果想访问,主构造器的参数要定义成成员属性,就是val或者var
User类写法进一步优化
优化前:
class User constructor() {
//kotlin中默认有get set方法
var username: String? = null
// ?表示可以赋值为null
var password: String? = null
var code: String? = null
//带参数的构造函数 : this() 调用无参主构造器
constructor(username: String?, password: String?, code: String?) : this() {
this.username = username
this.password = password
this.code = code
}
}
优化后:
//如果要定义一个数据类,都要重写toString()、hashCode()方法
//在Java中药自己手动生成
//在Kotlin中直接定义成数据类就可以了 用data class
data class User constructor(var username: String?, var password: String?,var code: String?) {
//空参构造器必须调用主构造器
constructor():this(null,null,null)
}
Kotlin中的==与===
Kotlin中的
==:其实是调用的equals方法
=== :比较的是地址值
Kotlin代码转化为Java代码
Tools-->Kotlin-->Show Kotlin Bytecode-->Decompile
以User类为例子:
转化前:
package com.example.app.entity
//如果要定义一个数据类,都要重写toString()、hashCode()、equals方法、copy方法
//在Java中需要自己手动生成
//在Kotlin中直接定义成数据类就可以l 用data class Kotlin会自动生成这些方法
data class User constructor(var username: String?, var password: String?,var code: String?) {
//空参构造器必须调用主构造器
constructor():this(null,null,null)
}
转换后:
package com.example.app.entity;
import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@Metadata(
mv = {1, 1, 15},
bv = {1, 0, 3},
k = 1,
d1 = {"\u0000$\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\u000e\n\u0002\b\u0010\n\u0002\u0010\u000b\n\u0002\b\u0002\n\u0002\u0010\b\n\u0002\b\u0002\b\u0086\b\u0018\u00002\u00020\u0001B\u0007\b\u0016¢\u0006\u0002\u0010\u0002B#\u0012\b\u0010\u0003\u001a\u0004\u0018\u00010\u0004\u0012\b\u0010\u0005\u001a\u0004\u0018\u00010\u0004\u0012\b\u0010\u0006\u001a\u0004\u0018\u00010\u0004¢\u0006\u0002\u0010\u0007J\u000b\u0010\u0010\u001a\u0004\u0018\u00010\u0004HÆ\u0003J\u000b\u0010\u0011\u001a\u0004\u0018\u00010\u0004HÆ\u0003J\u000b\u0010\u0012\u001a\u0004\u0018\u00010\u0004HÆ\u0003J-\u0010\u0013\u001a\u00020\u00002\n\b\u0002\u0010\u0003\u001a\u0004\u0018\u00010\u00042\n\b\u0002\u0010\u0005\u001a\u0004\u0018\u00010\u00042\n\b\u0002\u0010\u0006\u001a\u0004\u0018\u00010\u0004HÆ\u0001J\u0013\u0010\u0014\u001a\u00020\u00152\b\u0010\u0016\u001a\u0004\u0018\u00010\u0001HÖ\u0003J\t\u0010\u0017\u001a\u00020\u0018HÖ\u0001J\t\u0010\u0019\u001a\u00020\u0004HÖ\u0001R\u001c\u0010\u0006\u001a\u0004\u0018\u00010\u0004X\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\b\u0010\t\"\u0004\b\n\u0010\u000bR\u001c\u0010\u0005\u001a\u0004\u0018\u00010\u0004X\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\f\u0010\t\"\u0004\b\r\u0010\u000bR\u001c\u0010\u0003\u001a\u0004\u0018\u00010\u0004X\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\u000e\u0010\t\"\u0004\b\u000f\u0010\u000b¨\u0006\u001a"},
d2 = {"Lcom/example/app/entity/User;", "", "()V", "username", "", "password", "code", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", "getCode", "()Ljava/lang/String;", "setCode", "(Ljava/lang/String;)V", "getPassword", "setPassword", "getUsername", "setUsername", "component1", "component2", "component3", "copy", "equals", "", "other", "hashCode", "", "toString", "app_debug"}
)
public final class User {
@Nullable
private String username;
@Nullable
private String password;
@Nullable
private String code;
@Nullable
public final String getUsername() {
return this.username;
}
public final void setUsername(@Nullable String var1) {
this.username = var1;
}
@Nullable
public final String getPassword() {
return this.password;
}
public final void setPassword(@Nullable String var1) {
this.password = var1;
}
@Nullable
public final String getCode() {
return this.code;
}
public final void setCode(@Nullable String var1) {
this.code = var1;
}
public User(@Nullable String username, @Nullable String password, @Nullable String code) {
this.username = username;
this.password = password;
this.code = code;
}
public User() {
this((String)null, (String)null, (String)null);
}
@Nullable
public final String component1() {
return this.username;
}
@Nullable
public final String component2() {
return this.password;
}
@Nullable
public final String component3() {
return this.code;
}
@NotNull
public final User copy(@Nullable String username, @Nullable String password, @Nullable String code) {
return new User(username, password, code);
}
// $FF: synthetic method
public static User copy$default(User var0, String var1, String var2, String var3, int var4, Object var5) {
if ((var4 & 1) != 0) {
var1 = var0.username;
}
if ((var4 & 2) != 0) {
var2 = var0.password;
}
if ((var4 & 4) != 0) {
var3 = var0.code;
}
return var0.copy(var1, var2, var3);
}
@NotNull
public String toString() {
return "User(username=" + this.username + ", password=" + this.password + ", code=" + this.code + ")";
}
public int hashCode() {
String var10000 = this.username;
int var1 = (var10000 != null ? var10000.hashCode() : 0) * 31;
String var10001 = this.password;
var1 = (var1 + (var10001 != null ? var10001.hashCode() : 0)) * 31;
var10001 = this.code;
return var1 + (var10001 != null ? var10001.hashCode() : 0);
}
public boolean equals(@Nullable Object var1) {
if (this != var1) {
if (var1 instanceof User) {
User var2 = (User)var1;
if (Intrinsics.areEqual(this.username, var2.username) && Intrinsics.areEqual(this.password, var2.password) && Intrinsics.areEqual(this.code, var2.code)) {
return true;
}
}
return false;
} else {
return true;
}
}
}
这样就可以看出Kotlin中数据类 data class 自动帮助我们生成了getter 、setter、copy()、toString()、hashCode()、equals方法
Kotlin中的 ?:
var date = lesson.date?:"默认数据"
这一行代码的意思是:lesson.date 为null吗? 不为null就取lesson.date的值,为null就取默认数据
Kotlin中的when可以有返回值
kotlin中 if、try catch也可以有返回值
优化前:
if (state != null) {
setText(R.id.tv_state, state.stateName())
var colorRes = R.color.playback
when (state) {
Lesson.State.PLAYBACK -> colorRes = R.color.playback
Lesson.State.LIVE -> colorRes = R.color.live
Lesson.State.WAIT -> colorRes = R.color.wait
}
val backgroundColor = itemView.context.getColor(colorRes)
getView<View>(R.id.tv_state).setBackgroundColor(backgroundColor)
}
优化后:
if (state != null) {
setText(R.id.tv_state, state.stateName())
var colorRes = when (state) {
Lesson.State.PLAYBACK -> R.color.playback
Lesson.State.LIVE -> R.color.live
Lesson.State.WAIT -> R.color.wait
}
val backgroundColor = itemView.context.getColor(colorRes)
getView<View>(R.id.tv_state).setBackgroundColor(backgroundColor)
}
自定义操作符operator
var list: List<String> = ArrayList()
kotlin中取集合元素用:list[index]
其实点击进去看,会发现调用的就是get ,这是自定义操作符operator []-->get
public operator fun get(index: Int)
Kotlin中的循环语句
优化前:for in
val playbackLessons = ArrayList<Lesson>()
for (lesson in lessons) {
if (lesson.state === Lesson.State.PLAYBACK) {
playbackLessons.add(lesson)
}
}
activity.showResult(playbackLessons)
优化后:forEach
val playbackLessons = ArrayList<Lesson>()
lessons.forEach {
if (it.state === Lesson.State.PLAYBACK) {
playbackLessons.add(it)
}
}
activity.showResult(playbackLessons)
优化后:filter
//过滤掉 it.state === Lesson.State.PLAYBACK 返回一个过滤后的数据
val playbackLessons = lessons.filter { it.state === Lesson.State.PLAYBACK }
activity.showResult(playbackLessons)
repeat 、until
repeat(10){
println(it)
}
for(i in 0 until 10){
println(i)
}
会打印出0---9
Kotlin可以函数嵌套函数
方法嵌套好处:在别的地方就调用不到这个方法;方便找代码;内部函数可以访问外部函数的属性
方法嵌套劣势:每次调用的时候会额外生成一个对象,不建议循环调用
嵌套之前:
private fun login() {
//Java 中的final 表示不可变引用 getText kotlin中直接.text
val username:String = et_username.text.toString()
val password:String= et_password.text.toString()
val code:String= et_code.text.toString()
//Kotlin 中创建对象不用new
val user: User = User(username,password,code)
if(verify(user)){
CacheUtils.save(usernameKey, username)
CacheUtils.save(passwordKey, password)
//Kotlin中 LessonActivity.class 要写成LessonActivity::class.java
//Kotlin中获取class 用LessonActivity::class 要转化成java中class-->LessonActivity::class.java
startActivity(Intent(this, LessonActivity::class.java))
}
}
private fun verify(user: User): Boolean {
if(user.username!=null && user.username!!.length<4){
toast("用户名不合法")
return false
}
if (user.password != null && user.password!!.length < 4) {
toast("密码不合法")
return false
}
return true
}
嵌套之后:
private fun login() {
//Java 中的final 表示不可变引用 getText kotlin中直接.text
val username: String = et_username.text.toString()
val password: String = et_password.text.toString()
val code: String = et_code.text.toString()
//Kotlin 中创建对象不用new
val user: User = User(username, password, code)
//方法嵌套好处:在别的地方就调用不到这个方法;方便找代码;内部函数可以访问外部函数的属性
//方法嵌套劣势:每次调用的时候会额外生成一个对象,不建议循环调用
fun verify(): Boolean {
if (user.username != null && user.username!!.length < 4) {
toast("用户名不合法")
return false
}
if (user.password != null && user.password!!.length < 4) {
toast("密码不合法")
return false
}
return true
}
if (verify()) {
CacheUtils.save(usernameKey, username)
CacheUtils.save(passwordKey, password)
//Kotlin中 LessonActivity.class 要写成LessonActivity::class.java
//Kotlin中获取class 用LessonActivity::class 要转化成java中class-->LessonActivity::class.java
startActivity(Intent(this, LessonActivity::class.java))
}
}
getter与setter、@JvmStatic 及 @get的使用
优化前:
class BaseApplication : Application() {
//object 修饰的对象中的变量和函数都是静态的,
//我们只想让类中的一部分函数和变量是静态的就用伴生对象
companion object {
lateinit var currentApplication: Context
@JvmStatic
fun currentApplication(): Context {
return currentApplication
}
}
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
currentApplication = this
}
}
优化后:
class BaseApplication : Application() {
//object 修饰的对象中的变量和函数都是静态的,
//我们只想让类中的一部分函数和变量是静态的就用伴生对象
companion object {
//会自动生成 getter与setter
@JvmStatic
//自定义获取Context 的文件名
@get:JvmName("currentApplication")
lateinit var currentApplication: Context
//让setter不能访问
private set
}
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
currentApplication = this
}
}
使用=进行函数简化
简化前:
//Unit代表没有
@JvmStatic
fun save(key: String?, value: String?): Unit {
SP.edit().putString(key, value).apply()
}
//String? 返回值后面加上一个问号,代表返回值可能为null
@JvmStatic
fun get(key: String?): String? {
return SP.getString(key, null)
}
简化后:
@JvmStatic
fun save(key: String?, value: String?): Unit = SP.edit().putString(key, value).apply()
@JvmStatic
fun get(key: String?): String? = SP.getString(key, null)