中缀表达式(infix)
代码更加简洁易懂 c1 f1 10,相当于方法调用c1.f1(10)
可以自定义操作符,元组中的to就是中缀表达式
必须是成员函数或扩展函数
函数必须只有一个参数,函数参数不能是默认参数或可变参数
在函数前面加上infix
fun main() {
val c1 = C1()
c1.f1(10)
//调用中缀表达式
c1 f1 10
}
class C1{
//中缀表达式
infix fun f1(num:Int){
}
}
//作为顶层函数时,需要使用扩展函数
infix fun <T,R> T.to(name:R){
}
infix fun Int.until(name:String){
}
委托代理
类委托
代理模式,相当于相同类型的对象,一个对象中包含另一个相同类型对象,使用这个对象完成方法的实现
定义一个接口,定义两个类实现此接口
其中一个类中的方法,使用另一个对象调用
kotlin中代理使用by关键字,关联被代理对象
默认被代理类
public class DelegateDemo {
public static void main(String[] args) {
//创建代理
Jjr jjr = new Jjr();
//调用代理
jjr.say("拍戏");
}
}
//被代理类
class Mx implements IDelegate {
@Override
public void say(String s) {
System.out.println("mx say:" + s);
}
}
//代理类
class Jjr implements IDelegate {
//被代理对象
Mx mx = new Mx();
@Override
public void say(String s) {
//外界调用代理方法,代理对象调用了被代理方法
mx.say(s);
}
}
interface IDelegate {
void say(String s);
}
fun main() {
val i: I1 = C3()
i.say()
}
class C2 : I1 {
override fun say() {
println("我是c2")
}
}
//kotlin中代理使用by关键字
class C3 : I1 by C2() {
}
interface I1 {
fun say()
}
传递被代理类
public class DelegateDemo {
public static void main(String[] args) {
Mx mx = new Mx();
//创建代理
Jjr jjr = new Jjr(mx);
//调用代理
jjr.say("拍戏");
}
}
class Mx implements IDelegate {
@Override
public void say(String s) {
System.out.println("mx say:" + s);
}
}
//代理类
class Jjr implements IDelegate {
//被代理对象
private final IDelegate delegate;
public Jjr(IDelegate delegate) {
this.delegate = delegate;
}
@Override
public void say(String s) {
//外界调用代理方法,代理对象调用了被代理方法
delegate.say(s);
}
}
interface IDelegate {
void say(String s);
}
fun main() {
val i: I1 = C3(C2())
i.say()
}
class C2 : I1 {
override fun say() {
println("我是c2")
}
}
class C3(val delegate: I1) : I1 by delegate {
//如果本类需要处理,则可以重写代理方法
override fun say() {
//逻辑处理...
delegate.say()
//逻辑处理...
}
}
interface I1 {
fun say()
}
属性委托
将属性的get/set方法委托给其他对象
底层其实就是get/set方法作为代理方法
使用by关键字时,需要在代理类中重写getValue方法
class C11 {
val num: Int by C22()//委托给C22
}
class C22 {
operator fun getValue(c11: C11, property: KProperty<*>): Int {
return 20
}
operator fun setValue(c11: C11, property: KProperty<*>, i: Int) {
}
}
by lazy和lateinit
by lazy懒加载
属于属性委托
可以作为顶层变量,可以作为类的成员,也可以是局部变量
只能使用val修饰
使用时才初始化,加载时,只加载一次,返回值是高阶函数的最后一行
线程安全,不会初始化多次
fun main() {
val n by lazy { "" }
}
class C33 {
val n by lazy { "" }
}
val j by lazy { "" }
lateinit var 延迟加载
定义时不能初始化,使用变量的时候才赋值
可以顶层变量,可以作为类的成员,也可以作为局部变量
不能定义基本数据类型
没有lateinit val
fun main() {
lateinit var namea: String
}
class C33 {
lateinit var name1: String
}
lateinit var name: String
object
单例类,底层变量都是静态,方法不是静态
应用场景,类中字段不多的时候,可以使用object
object Util{
}
伴生对象
相当于java中的静态
不能使用对象访问伴生对象中的属性和方法
class Util private constructor(){
companion object{
val INSTANCE by lazy { Util() }
}
}
数据类(data class)
底层java生成了多个辅助方法
构造函数,get/set,hashCode,equals,copy
data class News(val id: String, var title: String)
fun main() {
//数据类的解构,简写
val (i, t) = News("1", "标题")
println(i)
println(t)
}
data class News(val id: String, var title: String)
密封类(sealed class)
相当于超强枚举
sealed class C5 {
class c51 : C5() {}
class c52 : C5() {}
class c53 : C5() {}
}
class c54 : C5()