kotlin
修饰符
可见性修饰符
类成员 | 顶层声明 | ||
---|---|---|---|
public | 默认可见性 | 所有地方可见 | 所有地方可见 |
private | 类中可见 | 文件中可见 | |
protected | 子类中可见 | ||
internal | 模块中可见 | 模块中可见 |
子类可重写的条件
- 父类中被open的方法
- 子类继承了抽象类,抽象方法必须被重写
- 子类继承的父类里的override方法
vararg 用来表示多个参数,类似于java中…
fun test(vararg tags: String) {
println(tags[0])
var list = listOf(*tags)
println(list)
}
var 与val的区别
区别 | |
---|---|
var | private |
val | private final |
out 关键字
枚举
enum class TimeTypeEnum(val value: String) {
LATESTWEEK("1"),
LATESTMONTH("2"),
LATESTYEAR("3")
}
until [0 x)
for(key in 0 until normal_praise){
LogUtil.d("=====key===${key}")
}
Any
var flag:Any="ddd"
Object flag = "ddd";
- Any是所有类型的超类型,是所有类型的根,包括基本数据类型
const 的作用
默认java调用kt的静态属性是需要调用getXX()的
Cat.Companion.getAge() //访问Cat.kt 文件的age属性
用 const 修饰后 相当于以 public staic final 的属性直接暴露给java
Cat.age
? 表示该引用可以为null
!! 非空,如果标记的变量是null会直接报错
val str:String?=null
println(str.toString()) //打印null
println(str!!.toString()) //会报错,此时断言str不为null
as
final
open 关键字
- 用来修饰父类以及父类中需要被重写的方法甚至是属性
- java中的类和方法默认都是open,但kt里都是final
- 子类中重写的方法可以显示的用final标注,从而使继承该子类的类不再重写该方法
- 抽象类中抽象方法和抽象属性都是默认open的,而实现的方法和属性都是final,要想重写必须手动添加open
object
- 接口中可以写方法的实现
- 单继承,多接口实现
interface CallBack {
fun callBack(str: String)
fun getTest(){
println("调用了接口里的方法")
}
}
abstract
companion object
- 需要在类中定义静态方法或者静态变量 (也就是android中的工具类或者一些常量)
class Cat {
companion object {
var name:String="hcy"
fun getName(){
println(name)
}
}
}
object 修饰的类
- 静态类
- 单例
- 方法和变量都是静态的
object Dog {
var name:String?=null
val age:Int=10
fun play(){
println("playing!!!!")
}
}
public final class Dog {
@Nullable
private static String name;
private static final int age = 10;
public static final Dog INSTANCE;
@Nullable
public final String getName() {
return name;
}
public final void setName(@Nullable String var1) {
name = var1;
}
public final int getAge() {
return age;
}
public final void play() {
String var1 = "playing!!!!";
boolean var2 = false;
System.out.println(var1);
}
private Dog() {
}
static {
Dog var0 = new Dog();
INSTANCE = var0;
age = 10;
}
}
is 类型的检查和转换
- 一旦被检查过的类型,不需要额外的转换就能直接引用属于这个类型的成员
v is String
v instanceof String
字符串
原始字符串
//原始字符串
fun func1(){
var str1="hcy\n"
val str="""hcy\n"""
for (c in str){
println(str.length)
}
}
- 原始字符串用三个引号,
内部没有转义
遍历字符串的写法
for in
fun strTest(str:String):Unit{
for (c in str){
println(c)
}
}
控制语句
if
fun funcIf(a: Int, b: Int) {
var max = if (a < b) {
a
} else {
b
}
println("max==${max}")
}
when
- switch
- 代码块中的最后一句是返回值
fun funcWhen(tag:Any):Unit{
when(tag){
1-> println("AAAA")
2-> println("BBBB")
3-> println("CCCC")
4,5->{
println("DDDD=or=EEEE")
}
in 6..8->{
println("在[6,8]区间里")
}
is Int->{
}
else -> println("其他")
}
}
kt 三目表达式的写法
kt 不支持三目表达式
集合
list
forEach
var arr=Array(5){i->i}
arr.forEach {
println(it)//0,1,2,3,4
}
数组的创建
var arr=Array(5){i->i}
基本数据类型的数组(未装箱的数组)
var a= IntArray(5)
- 创建了一个基本数据类型的数组,长度为5,每个默认值为0
基本类型装箱后的数组转为基本数据类型的数组
toIntArray()
遍历数组下标索引
fun funcFor2():Unit{
var arr= arrayOf("AAA","BBB",333,444,555);
for (index in arr.indices){
println("index==${index},value==${arr[index]}")
}
}
遍历数组的下标和值
a.forEachIndexed { index, value ->
println("基本数据类型的数组$index===$value")
}
遍历list的下标和值
fun funcFor():Unit{
var arr= arrayOf("A",2,3)
for ((i,v)in arr.withIndex()){
if (v is String){
println("String类型:index==${i},value==${v}")
}else{
println("index==${i},value==${v}")
}
}
}
map
遍历map的key value
for ((key,value) in params){
Log.d("主app参数::","key==${key},value==${value}")
}
集合的过滤
filter
val filterList =
data.filter { !(it.class_guid.equals(currentClass?.class_guid) && it.class_name.equals(currentClass?.class_name)) }
downTo step
10分钟倒计时
var total = 10 * 60 * 1000
for (i in total downTo 0 step 1000) {
Thread.sleep(1000)
println(i/1000)
}
异常
- 不区分受检异常和未受检异常,不用指定函数抛出的异常,可以处理或者不处理异常
函数
重写属性的set方法 field 关键字
var age: Int = 0
set(value) {
println("${name}age setter")
field = value
}
修改访问器的可见属性
外部 只能get不能set
var address: String = ""
private set
委托 by 关键字(像是装饰者模式代码简化版)
- 一个旧接口
interface Person {
var name: String
var age: Int
}
- 一个需要被扩展的类(这个类实现了旧接口)
class OldStu(override var name: String, override var age: Int) : Person {
}
- 一个扩展的新类
class Student(var per: OldStu, var sex: String) : Person by per {
fun getInfo() {
println("${per.age}==${per.name}===$sex")
}
}
扩展函数
- 类的扩展函数是不能访问类的private 和 protected 成员
- 类的成员函数,要定义在类的外面
- 可以直接被扩展的类的其他方法和属性,但不能访问私有的或者是受保护的成员
Android&&Kotlin
启动activity
startActivity(Intent(MainActivity@this,LoginActivity::class.java))
点击事件的写法
tv_refresh?.setOnClickListener {
present.getStudentContacts(
SPUtils.getInstance().getString(TeacherConstants.YID),
currentClassGuid,
"",
getThisActivity()
)
}
kotlin 接口回调的写法
声明带返回值的方法不一定都要返回值类型
=
fun getTest(num:Int)=when(num){
1->{
"1"
}
else->{
"ddd"
}
}
伴生对象
是声明在类中的普通对象
- 代替了java中的静态方法和静态变量
- 可以实现接口,并且可以受用扩展函数和属性y
lambda 使用
调用对象的属性
对象::属性
函数式编程
var position = 0
val result = it.map { poi: PoiInfo ->
MyPoi(poi, position++ == 0)
}.sortedBy { myPoi: MyPoi ->
//按照poi的坐标到定位的坐标的距离做升序排序
BdMapUtils.getDistance(
myPoi.poi!!.location, LatLng(
current!!.latitude,
current!!.longitude
)
)
}
惰性求值 :序列
- 惰性求值会比及早求值性能高
- 惰性求值是逐个的,及早求值可能是批量的
序列的操作
- 中间操作 返回另一个序列
- 末端操作 返回的是结果 末端操作执行了所有延期的计算
函数式接口
只有一个抽象方法的接口
?. 安全调用符
不为null会往下执行,为null调用就不发生
?: 空合并运算符
isNullOrBlank isNullOrEmpty 区别
- isNullOrBlank 判断null,"","\r" 如果字符串里有转义字符,会判断
- isNullOrEmpty 判断null,""
泛型默认是可空的 Any?
fun <T> fun5(a: T) {
}
指定泛型不为null
fun <T:Any> fun5(a: T) {
}
kt不区分基本数据类型和引用类型
Unit Void Nothing
Nothing | 没有任何的值,这个函数永不返回,通常用来抛出异常 |
Unit | 具备java中void的功能,可以作为参数类型 |
kt中集合是允许存放null的
只读集合
- 只读集合不一定是不可变的
- 只读集合并不总是线程安全的
- set,map,list 都是只读 实现的是connection接口
可变集合
- hashset hashmap arraylist 是可变的,也就是可添加的,实现的是mutableconnection
平台类型
java 中的类型在kt中被解释成平台类型,可以把它当做null或者非null对待
运算符重载
operator
表示将函数作为相应的约定的实现
重载二元算术运算符
a+b plus
data class OldStu(var name: String, var age: Int) : Person {
operator fun plus(otherage: OldStu): Int {
return age + otherage.age
}
}
fun fun9() {
println(OldStu("hcy", 22) + OldStu("hcy1", 33))
}
plusAssgin 暂时没搞懂,貌似是可变集合定义的
重载一元运算符
+a unaryPlus
data class OldStu(var name: String, var age: Int) : Person {
operator fun plus(otherage: OldStu): Int {
return age + otherage.age
}
operator fun unaryPlus():Int{
return age +1
}
}
println(+OldStu("hcy,", 22))
自定义下标运算符 get set
data class OldStu(var name: String, var age: Int) : Person {
operator fun plus(otherage: OldStu): Int {
return age + otherage.age
}
operator fun unaryPlus(): Int {
return age + 1
}
operator fun get(index: Int): String {
return when (index) {
0 -> {
name
}
1 -> {
"$age"
}
else -> {
throw Exception()
}
}
}
}
fun fun12() {
var stu=OldStu("hcy",21)
println(stu[0])
println(stu[1])
}
[index] | get/set |
contains | in |
1…10 | rangeTo |
for(in) | iterator |
解构声明
组件函数
- data class 自带组建函数,不需要自己定义组件函数
- 组件函数的定义 operator fun component1()=name,函数名必须是component+数字
委托属性
高阶函数
- 以另一个函数作为参数或者返回值的函数
函数类型
声明函数类型
(参数类型)->返回类型
- 返回类型可空
fun fun14(a: Int, b: Int): (Int, Int) -> Int {
val sum: (Int, Int) -> Int = { x, y -> x + y }
//声明可null的函数类型
var test: ((String?, String?) -> String)? =
{ x, y -> "$x+$y" }
println(sum(a, b))
println(test?.let { it(null, null) })
return sum
}
fun fun15(a: Int, b: (test: String) -> Unit): Unit {
b("ttt")
println(a)
}
fun14(1, 2)
var s: (String) -> Unit = {
println(it)
}
fun15(6666) { y ->
println(y)
}