上面只是说了调用的地方,实际上调用还是需要使用receiver进行调用。 扩展函数的限制 前面介绍了扩展函数实现的原理并且看到了扩展函数的作用域信息,接下来分析下扩展函数在哪些场景下会被限制。...静态扩展函数 首先来回顾下普通的静态函数/变量如何定义,在Kotlin中使用伴生对象类将函数/变量定义在其中,那么该函数/变量就是静态函数/变量了。...,其是定义了一个Companion的静态内部类然后再该类中定义了这些静态变量和方法 和普通函数/变量一样,扩展函数也是一样的定义方式,在伴生对象中定义扩展函数: fun Son.Companion.foo...这样似乎看起来没有什么问题,但是当我们需要扩展三方类的静态函数时,如果其没有用Kotlin的伴生对象指定静态方法/变量,那么该方案将无法使用,只能用实例去调用。...函数优先级 有没有想过这样一种情况:就是这个类扩展的函数名之前在这个类中就已经存在了,那么调用这个方法时,会调用扩展函数还是之前类中定义好的方法。
单例的懒汉式与恶汉式 II . Java 中的懒汉式与恶汉式 III . Kotlin 中对应 Java 的懒汉式与恶汉式 IV . Kotlin 对象 ( object ) 声明 V ....Kotlin 伴生对象 ( companion object ) VI . ? 与 !! 作用 I . 单例的懒汉式与恶汉式 ---- 1 ....单例类简介 : 单例是保证在应用程序的内存中 , 只存在一个实例的设计模式 ; ① 饿汉式 : 这个类只要一声明对象 , 只要该类被调用到 , 不管有没有用到其单例对象 , 必须马上创建一个该单例对象...Kotlin 懒汉单例模式 : 该示例中涉及到了伴生对象 , 字段 getter 方法定义 , ? 和 !!...= null //这是 Kotlin 中特有的 get set 方法定义方式 // 在成员变量的下面可以直接定义该成员的 get() set() 方法
因此,每当从Map中获取一个元素时,它需要被转换为实际类型。而在CoroutineContext类中,更加通用的get方法实际上是根据作为参数传递的Key的泛型来定义返回的Element类型。...每个Key被定义为其相关元素接口或类的伴生对象。这样,Key可以通过使用元素类型的名称直接被引用。...在构建器函数中,我们实际上可以看到三个上下文在起作用。 CoroutineScope接收器是由它提供CoroutineContext的方式来定义的,这是继承的上下文。...MainScope辅助工厂函数被用来创建一个具有预定义的UI dispatcher和supervisor job的作用域。...在作用域的上下文中定义元素,是在使用上下文的地方,覆盖库的默认值的一种方式。该作用域还提供了一个job,因此从该作用域启动的所有coroutine都有同一个父级。
不过,Kotlin 中可以用 object 关键字直接定义一个对象,在类内部,我们可以用 companion 为类声明一个伴生对象。...伴生对象的成员可通过只使用类名作为限定符来调用,伴生对象的成员看起来像 Java 的静态成员,在运行时他们仍然是真实对象的实例成员。...伴生对象 Kotlin 中可以用 object 关键字直接定义一个对象,在类内部,我们可以用 companion 为类声明一个伴生对象。...伴生对象的成员可通过只使用类名作为限定符来调用,伴生对象的成员看起来像 Java 的静态成员,在运行时他们仍然是真实对象的实例成员。...对于 Optional 类型的成员变量,如果没有显式地初始化,编译器会自动把它初始化为 nil。对于非 Optional 类型的成员变量,必须显式地初始化。
扩展函数是静态解析的,并未对原类添加函数或属性,对类本身没有任何影响。 扩展属性允许定义在类或者kotlin文件中,不允许定义在函数中。...,只能由getters/setters显式提供!...3.伴生对象-扩展函数和属性 可为伴生对象定义扩展函数和属性: class MyClass { companion object { } //伴生对象 } fun...MyClass.Companion.foo() { // …… } MyClass.foo() //用类名调用 4.作用域 1.扩展直接在包中 在顶层定义扩展(即直接在包中...prototype就是“一个给类的对象添加方法的方法”,使用prototype属性,可以给类动态地添加方法 语法 object.prototype.name=value 实例 在本例中,我们将展示如何使用
(3)大括号{}用来划分作用域,{}的返回值为最后一个语句的值。 (4)句点符号.表示方法,可以用空格代替。 (5)冒号:用来说明变量的数据类型。 (6)=>用来表示匿名函数的映射关系。...类的定义中可以用private声明为私有属性和私有方法,只允许在类的作用域访问,不允许在类的外部访问。 可以用protected声明为受保护的属性和方法,只允许在类作用域及其子类作用域中访问。...其余属性和方法默认为公有属性和公有方法,可以在类的作用域外访问。 此外还可以在private或protected后面用方括号加上作用域保护,表示方括号中的类和对象不受访问限制。...实践中我们一般用apply方法来构造对象,而无需用new声明一个对象,从而相当于一个语法糖。 unapply方法是apply方法的逆方法,我们一般用它来从对象中反推得到其构造参数。...name是对象标识符,type是它的类型,{}括起来的作用域部分都是它的值。 从变量的定义,函数的定义,判断语句,循环语句到类的定义,都可以看成是这个格式省去某些部分的特例或语法糖等价书写形式。
这是好的语言设计,因为你不应该改变方法的参数。但是你可以用相同的名称定义另一个变量,并按照你想要的方式初始化。现在,在这个方法级别的范围中你拥有两个叫做 num 的变量。...当然,同一时间你只能访问其中一个num,所以 num 的值会改变。将军,无解了。 在 if 主体中,你可以添加另一个 num,这并不令人震惊(新的块级别作用域)。...似乎Java互操作性破坏了Kotlin的杀手特性——类型推断。看起来您应该显式地声明类型(如T?),以满足由Java方法填充的所有Kotlin变量。 ? 类字面量 ?...另一种情况,如果参数是按分行的格式写出来的,你还得去寻找返回类型。要在下面这个方法定义中找到返回类型,你需要花多少时间? ? 关于相反顺序的第三个问题是限制了IDE的自动完成功能。...“它是与类绑定的一个单例对象。你可以把日志记录器放在伴生对象中,” Kotlin 如此解释。 “明白了。是这样吗?” ? “对!
导航 学完本篇,你将了解到以下内容: 密封类构造函数传值的使用细节; 内联函数,你应该注意的地方; 伴生对象隐藏的性能问题; lazy ,可能没你想的那么简单; apply !...错误示例 sealed 初始化 如题,我们有一个公用的属性 sum ,为了便于复用,我们将其抽离到 Fruit 类构造函数中,让子类便于初始化时传入,而不用重复显式声明。...伴生对象,也许真的不需要 在 Kotlin 中,我们不能像 Java 一样,随便定义一个静态方法或者静态属性。此时 companion object(伴生对象)就会派上用场。...Book 类中增加了一个伴生对象,其中有一个静态的字段 SUM_MAX。...=构造者模式 apply 作为开发中的常客,为我们带来了不少便利。其内部实现也非常简单,将我们的对象以函数的形式返回,this 作为接收者。从而以一种优雅的方式实现对对象方法、属性的调用。
因此不允许将对象表达式定义成抽象类。 对象表达式不能定义构造器。但对象表达式可以定义初始化块,可以通过初始化块来完成构造器需要完成的事情。 对象表达式可以包含内部类,不能包含嵌套类。...Kotlin的对象表达式可访问或修饰其作用域内的局部变量。...对象声明不能定义在函数和方法内;但对象表达式可嵌套在其他对象声明或非内部类中。...三、伴生对象和静态成员 在类中定义的对象声明,可使用companion修饰,这样该对象就变成了伴生对象。...四、伴生对象的扩展 伴生对象也可以被扩展。如果一个类具有伴生对象,则Kotlin允许为伴生对象扩展方法和属性。
伴生对象的总结 ---- 类似于 Java 中使用类访问静态成员的语法。因为 Kotlin 取消了 static 关键字,所以 Kotlin 引入伴生对象来弥补没有静态成员的不足。...可见,伴生对象的主要作用就是为其所在的外部类模拟静态成员。 注意: 每个类可以最多有一个半生对象; 使用 const 关键字修饰常量,类似于 Java 中的 static final修饰。...首先伴生对象中的代码是在类加载时就会执行。init代码块中的方法会按顺序放在主构造函数中,主构造函数中原来的代码会在后面执行。 9. const 和 val 有什么区别?...如果这些函数中的任何一个在类体中显式定义或继承自其基类,则不会自动生成该函数。如果变量是 val 修饰,只会生成 get 方法。 11. 什么是 Range 操作符?...---- Range 是 Kotlin 相对 Java 新增的一种表达式,它表示的是值的范围,类似于数学中的区间。
在 Kotlin 中方法参数是一个值,所以你不能改变 num 参数。这是好的语言设计,因为你不应该改变方法的参数。但是你可以用相同的名称定义另一个变量,并按照你想要的方式初始化。...在 if 主体中,你可以添加另一个 num,这并不令人震惊(新的块级别作用域)。 好的,在 Kotlin 中,inc(1) 输出 2。但是在Java中,等效代码将无法通过编译。...为什么Kotlin从Java的T类型推断到T!而不是T?呢?似乎Java互操作性破坏了Kotlin的杀手特性——类型推断。看起来您应该显式地声明类型(如T?)...“它是与类绑定的一个单例对象。你可以把日志记录器放在伴生对象中,” Kotlin 如此解释。 “明白了。是这样吗?”...古老而友好的 public static void main() 仍然是启动 Java 应用的唯一方式。在没有Google的帮助下尝试着写出这个伴生对象。
正文 object 的三种用法 Kotlin 的 object 关键字有三种用法: 对象声明 ,一般用来实现单例 伴生对象 ,类似 Java 的 static 关键字,也可以用于工厂方法模式 对象表达式...通常我们可以在顶层文件中直接定义常量和顶层函数,但有的时候我们的确需要在类中定义静态常量或函数,这样显得更加直观。这就是 伴生对象 的应用场景。...再回想一下前面说过的, object 其实我们可以把它理解成 定义一个类并创建一个实例 。 伴生对象仍旧符合这一语义。 在 Java 中如何调用伴生对象呢?...在 Java 中就可以用 User.X.isMale(1) 了。 了解了伴生对象的本质之后,再来说两个它的其他用法。...伴生对象扩展方法 伴生对象也是支持扩展方法的。还是以上面的 Car 为例,定义一个根据汽车品牌获取汽车类型的扩展方法。
平台类型标识法 如上所述,平台类型不能在程序中显式表述,因此在语言中没有相应语法。 然而,编译器和 IDE 有时需要(在错误信息中、参数信息中等)显示他们,Koltin提供助记符来表示他们: T!...` } 类型限定符默认值 @TypeQualifierDefault 引入应用时在所标注元素的作用域内定义默认可空性的注解。...如果对这些函数使用@JvmStatic进行标注,那么Kotlin还可以为在命名对象或伴生对象中定义的函数生成静态方法。..., 使其 getter 和 setter 方法在该对象或包含该伴生对象的类中是静态成员。...该注解可以用于构造函数、静态方法中,但不能用于抽象方法和在接口中定义的方法。
上次介绍了kotlin的类定义与初始化,接下来学习对象、接口、抽象类 一、对象 1.object关键字 object,类似Java中的静态 三种使用方式: 1.1 对象声明 对应Java中的单例类,只会在内存中实例化一次...如果你想要某个对象和一个类实例化绑定在一起,可以考虑伴生对象,使用 companion object 可以在一个类里定义一个伴生对象,一个类只能有一个伴生对象, 伴生对象也是静态的,只会在类实例化或调用伴生对象中的内容...println(data) } 结果: com.aruba.mykotlinapplication.NormalClz@5e481248 DataClz(x=10, y=10) 注意:数据类自动实现的个性化只对主构造函数里的定义的参数起作用...7.运算符重载 之前使用集合是我们可以直接使用 "+" 、"-" 等来添加和删除元素 和c++一样,kotlin也支持运算符重载,只需要重载下面的函数就可以实现了: 8.枚举类 用来定义常量集合的一种特殊类...,可以使用密封类,使用sealed修饰类,来实现更加复杂的定义,密封类可以更灵活的控制某个子类型 子类型必须和它定义在同一个文件里 sealed class Position { //使用object
例如 Java 中是 String 类型的对象,要在 Kotlin 中使用的话,需要用 String? 类型来接收。 4. Kotlin 没有静态变量和静态方法。...扩展函数 kotlin 支持给原有的类添加一些扩展的功能,就是通过扩展函数来实现的。可以针对第三方库中对象添加一些我们需要的方法。...block 函数是作为一个参数,所以返回类型要显式写出 fun Onlyif(isDebug: Boolean, block: () -> Unit) { if (isDebug) block(...可以实现静态方法和静态变量: class StringUtils { // 伴生对象 companion object { // 伴生对象实现静态变量 val...可以使用伴生对象来实现 kotlin 的单例: // 单例实现 class SingleInstance private constructor() { companion object {
调用上面集合的方式如下: 6,伴生对象 Kotlin中没有静态属性和方法,如果我们要创建单列,可以使用Object关键字声明类。...伴生对象的调用跟Java一样,通过类名.属性名称或函数名称调用。 新特性 1,空安全 在Kotlin中,对象声明分为可空引用和非空引用两种。...在Java中泛型是不变的,比如:虽然A继承B,但List和List之间没有任何关系,Java是通过泛型通配符来实现型变的: 3,反射 反射是运行于JVM中的程序检测和修改运行时的一种行为,通过反射可以在运行时获取对象的属性和方法...Kotlin中的反射如下。 要调用具体的对象时,可以不通过KClass对象,直接调用方法和访问属性。...6.2.3 静态解析 6.2.4 扩展属性 6.2.5 扩展伴生对象 6.2.6 扩展的作用域 6.2.7 类中声明扩展 6.3 this表达式 6.5 小结 第7章 数据类与密封类 7.1 数据类
有任何问题,欢迎随时与我交流~ ---- 8.2 在Kotlin中使用函数式编程 好了亲,前文中我们在函数式编程的世界里遨游了一番,现在我们把思绪收回来,放到在Kotlin中的函数式编程中来。...为了让事情简单化(在Java 8中,增加Lambda表达式的支持),我们在Kotlin中使用普通的函数来替代函数式接口。事实上,函数式编程中的函数,比C语言中的函数或者Java中的方法都要强大的多。...,显式声明返回类型是可选的: fun double(x: Int) = x * 2 8.2.7 函数作用域 在 Kotlin 中函数可以在文件顶层声明,这意味着你不需要像一些语言如 Java、C# 或...此外除了顶层函数,Kotlin 中函数也可以声明在局部作用域、作为成员函数以及扩展函数。...8.2.10 尾递归tailrec Kotlin 支持一种称为尾递归的函数式编程风格。 这允许一些通常用循环写的算法改用递归函数来写,而无堆栈溢出的风险。
5) 在 scala 中没有 public 关键字,即不能用 public 显式的修饰属性和方法。...隐式值 隐式值也叫隐式变量,将某个形参变量标记为 implicit,所以编译器会在方法省略隐式参数的情况下去搜索作用域内的隐式值作为缺省参数 scala package cn.buildworld.scala.day2...} } } 隐式解析机制 1) 首先会在 当前代码作用域下查找隐式实体(隐式方法、隐式类、隐式对象)。...(一般是这种情况) 2) 如果第一条规则查找隐式实体失败,会继续在隐式参数的类型的作用域里查找。...类型的作用域是指与该类型相关联的全部伴生模块,一个隐式实体的类型 T 它的查找范围如下( 第二种情况范围广且复杂在使用时,应当尽量避免出现): a) 如果 T 被定义为 T with A with
领取专属 10元无门槛券
手把手带您无忧上云