当前位置: 首页 > news >正文

利用css技术做网站的思路/西安百度推广运营公司

利用css技术做网站的思路,西安百度推广运营公司,平台企业是什么意思,网络推广方案下拉管家微xiala11扩展 Kotlin 提供了一种能力,无需继承类或使用像装饰器这样的设计模式,就能为类或接口扩展新的功能。这是通过一种名为扩展的特殊声明来实现的。 例如,你可以为无法修改的第三方库中的类或接口编写新的函数。这些函数可以像原类的方法一样以…

扩展

Kotlin 提供了一种能力,无需继承类或使用像装饰器这样的设计模式,就能为类或接口扩展新的功能。这是通过一种名为扩展的特殊声明来实现的。

例如,你可以为无法修改的第三方库中的类或接口编写新的函数。这些函数可以像原类的方法一样以常规方式调用。这种机制被称为扩展函数。此外,还有扩展属性,它允许你为现有类定义新的属性。

扩展函数

要声明一个扩展函数,需要在函数名前加上接收者类型,该接收者类型指的是要被扩展的类型。以下代码为 MutableList<Int> 添加了一个 swap 函数:

fun MutableList<Int>.swap(index1: Int, index2: Int) {val tmp = this[index1]this[index1] = this[index2]this[index2] = tmp
}

扩展函数内部的 this 关键字对应接收者对象(即那个在点号之前传递的对象)。现在,你可以在任何 MutableList<Int> 上调用这样的函数:

val list = mutableListOf(1, 2, 3)
list.swap(0, 2)

这个函数对于任何 MutableList<T> 都有意义,可以将它泛型化:

fun <T> MutableList<T>.swap(index1: Int, index2: Int) {val tmp = this[index1]this[index1] = this[index2]this[index2] = tmp
}

你需要在函数名之前声明泛型类型参数,以便它能在接收者类型表达式中使用。有关泛型的更多信息,请参阅泛型函数。

扩展是静态解析的

扩展实际上并不会修改它们所扩展的类。通过定义一个扩展,你并没有向类中插入新的成员,只是让新的函数可以通过点号表示法在该类型的变量上调用。

扩展函数是静态分发的。因此,调用哪个扩展函数在编译时就已经根据接收者类型确定了。例如:

open class Shape
class Rectangle : Shape()fun Shape.getName() = "Shape"
fun Rectangle.getName() = "Rectangle"fun printClassName(s: Shape) {println(s.getName())
}fun main() {printClassName(Rectangle()) // Shape
}

这个示例会打印出 Shape,因为所调用的扩展函数仅取决于参数 s 的声明类型,该声明类型为 Shape 类。

如果一个类有一个成员函数,同时又定义了一个扩展函数,且该扩展函数的接收者类型、名称都与成员函数相同,并且能应用于给定的参数,那么成员函数总是会被优先调用。例如:

class Example {fun printFunctionType() {println("Class method")}
}fun Example.printFunctionType() {println("Extension function")
}fun main() {Example().printFunctionType() // Class method
}

然而,扩展函数对同名但签名不同的成员函数进行重载是完全没问题的:

class Example {fun printFunctionType() {println("Class method")}
}fun Example.printFunctionType(i: Int) {println("Extension function")
}fun main() {Example().printFunctionType(1) // Extension function
}

可空接收者

请注意,扩展可以使用可空的接收者类型来定义。即使对象变量的值为 null,也可以在该变量上调用这些扩展函数。如果接收者为 null,那么 this 也为 null。因此,在定义具有可空接收者类型的扩展时,我们建议在函数体内部进行 this == null 检查,以避免编译错误。

Kotlin 中,你可以直接调用 toString() 方法而无需检查是否为 null,因为该检查已经在扩展函数内部完成了:

fun Any?.toString(): String {if (this == null) return "null"return toString()
}

扩展属性

Kotlin 对扩展属性的支持与对扩展函数的支持非常相似:

val <T> List<T>.lastIndex: Intget() = size - 1

由于扩展实际上并不会向类中插入成员,因此扩展属性无法高效地拥有幕后字段。这就是为什么扩展属性不允许使用初始化器的原因。扩展属性的行为只能通过显式提供 getter / setter 来定义。

示例:

// 错误:扩展属性不允许使用初始化器。
val House.number = 1

伴生对象扩展

如果一个类定义了伴生对象,你也可以为伴生对象定义扩展函数和扩展属性。

就像伴生对象的常规成员一样,调用它们时只需使用类名作为限定符:

class MyClass {// 该伴生对象将被称为 Companion。companion object { }
}fun MyClass.Companion.printCompanion() {println("companion")
}fun main() {MyClass.printCompanion()
}

扩展的作用域

在大多数情况下,你会在顶层直接在包下定义扩展:

package org.example.declarationsfun List<String>.getLongestString() { /*...*/ }

要在声明扩展的包之外使用该扩展,需在调用处导入它:

package org.example.usageimport org.example.declarations.getLongestStringfun main() {val list = listOf("red", "green", "blue")list.getLongestString()
}

将扩展声明为成员

你可以在一个类内部为另一个类声明扩展。在这样的扩展内部,存在多个隐式接收者,这些对象的成员可以无需限定符即可访问。声明扩展的类的实例被称为分发接收者,而扩展方法的接收者类型的实例被称为扩展接收者。

class Host(val hostname: String) {fun printHostname() { print(hostname) }
}class Connection(val host: Host, val port: Int) {fun printPort() { print(port) }fun Host.printConnectionString() {// 调用 Host.printHostname()。printHostname()print(":")// 调用 Connection.printPort()。printPort()}fun connect() {// 调用扩展函数。host.printConnectionString()}
}fun main() {Connection(Host("kotl.in"), 443).connect()// 错误,该扩展函数在 Connection 外部不可用。// Host("kotlin").printConnectionString()
}

如果分发接收者和扩展接收者的成员发生名称冲突,扩展接收者的成员优先。若要引用分发接收者的成员,你可以使用限定 this 语法。

class Connection {fun Host.getConnectionString() {// 调用 Host.toString()。toString()// 调用 Connection.toString()。this@Connection.toString()}
}

作为成员声明的扩展可以被声明为 open 并在子类中重写。这意味着此类函数的分发对于分发接收者类型是虚拟的,但对于扩展接收者类型是静态的。

open class Baseclass Derived : Base()open class BaseCaller {open fun Base.printFunctionInfo() {println("Base extension function in BaseCaller")}open fun Derived.printFunctionInfo() {println("Derived extension function in BaseCaller")}fun call(b: Base) {b.printFunctionInfo()}
}class DerivedCaller : BaseCaller() {override fun Base.printFunctionInfo() {println("Base extension function in DerivedCaller")}override fun Derived.printFunctionInfo() {println("Derived extension function in DerivedCaller")}
}fun main() {BaseCaller().call(Base()) // Base extension function in BaseCallerBaseCaller().call(Derived()) // Base extension function in BaseCallerDerivedCaller().call(Base()) // Base extension function in DerivedCallerDerivedCaller().call(Derived()) // Base extension function in DerivedCaller
}

输出结果及原因分析

BaseCaller().call(Base()):输出 Base extension function in BaseCaller

  • BaseCaller 类的 call 方法中,参数 b 的类型是 Base

  • 当调用 b.printFunctionInfo() 时,由于 bBase 类型,会调用 BaseCaller 类中为 Base 类定义的扩展函数 Base.printFunctionInfo(),所以输出 Base extension function in BaseCaller

BaseCaller().call(Derived()):输出 Base extension function in BaseCaller

  • 虽然传递给 call 方法的实际对象是 Derived 类型,但 call 方法的参数类型声明为 Base

  • 扩展函数是静态解析的,也就是说,调用哪个扩展函数是根据参数的声明类型来决定的,而不是实际类型。因此,这里仍然会调用 BaseCaller 类中为 Base 类定义的扩展函数 Base.printFunctionInfo(),输出 Base extension function in BaseCaller

DerivedCaller().call(Base()):输出 Base extension function in DerivedCaller

  • DerivedCaller 继承自 BaseCaller,并且重写了 Base 类的扩展函数 Base.printFunctionInfo()

  • 当调用 DerivedCaller().call(Base()) 时,call 方法在 BaseCaller 类中定义,但是在 DerivedCaller 实例上调用,由于 DerivedCaller 重写了 Base 类的扩展函数,所以会调用重写后的扩展函数,输出 Base extension function in DerivedCaller

DerivedCaller().call(Derived()):输出 Base extension function in DerivedCaller

  • 同样,call 方法的参数类型声明为 Base,扩展函数是静态解析的,根据参数的声明类型来决定调用哪个扩展函数。

  • 因为是在 DerivedCaller 实例上调用 call 方法,而 DerivedCaller 重写了 Base 类的扩展函数,所以会调用重写后的 Base 类的扩展函数,输出 Base extension function in DerivedCaller

可见性说明

扩展使用的可见性修饰符,与在相同作用域中声明的普通函数所用的可见性修饰符相同。例如:

  • 在文件顶层声明的扩展,可以访问同一文件中的其他 private 顶层声明。

  • 如果在接收者类型之外声明扩展,它无法访问接收者的 privateprotected 成员。

http://www.lryc.cn/news/580635.html

相关文章:

  • 苏州做网站最好公司有哪些/百度快照查询
  • 重庆做网站制作的公司/常见的网络推广方法有哪些
  • 企业邮箱怎么注册的/百度关键词seo排名
  • 企业网站主页设计模板/如何优化搜索引擎
  • 中和华丰建设有限责任公司网站/教育机构排名
  • wordpress手游/seo公司推广
  • 网站设计师岗位职责/宁德市教育局官网
  • 重庆智能网站建设价格/危机公关处理
  • 手机制作表格/seo推广是什么
  • 佛山市seo广告优化工具/搜索引擎优化关键词
  • 虚拟网站php专业型/百度seo收费
  • 江苏省建设工程考试网站/小吃培训去哪里学最好
  • dw做的网站如何使用/网站推广怎样做
  • 网站设计班培训/seo课程培训中心
  • 网站建设合同 域名/今日最新消息新闻报道
  • 重庆智能网站建设企业/网络营销的表现形式有哪些
  • 在xampp下搭建本地网站/免费软文发布平台有哪些
  • 网页升级未成年人自觉离开/北京网站优化多少钱
  • 大同市发改委门户网站医院建设/网页版百度
  • 企业建站免费代码/最有效的app推广方式有哪些
  • 手机微信网站建设/域名注册哪个平台比较好
  • 哪些网站做黑名单/国家反诈中心app下载
  • 十大永久免费网络游戏/青岛设计优化公司
  • 广西汽车网网站建设/色盲测试图第六版及答案大全
  • 学院网站建设管理办法/站长工具端口
  • 网站建设与维护 唐清安/上海谷歌优化
  • 科技小论文怎么写/公司seo排名优化
  • 长沙网站推广 下拉通推广/千万不要做手游推广员
  • flashfxp如何发布网站/做外贸有哪些网站平台
  • 做网站有什么好的推荐/网络营销技巧和营销方法