一 概述
二 扩展概述
2.1 概念
- 扩展可以为在当前 package 可见的类型(除函数、元组、接口)添加新功能
- 不能破坏原有类型的封装性,但希望添加额外的功能时,可以使用扩展
2.2 可以添加的功能
- 添加成员函数
- 添加操作符重载函数
- 添加成员属性
- 实现接口
2.3 不支持的功能
- 扩展不能增加成员变量。
- 扩展的函数和属性必须拥有实现。
- 扩展的函数和属性不能使用 open、override、 redef修饰。
- 扩展不能访问原类型 private 的成员
三 直接扩展
3.1 概念
直接扩展即不包含额外接口的扩展
3.2 定义
1 2 3 4 5
| extend String { public func printSize() { println("the size is ${this.size}") } }
|
3.3 使用
1 2 3 4
| main() { let a = "123" a.printSize() // the size is 3 }
|
四 接口扩展
4.1 概念
接口扩展即包含接口的扩展
4.2 定义
1 2 3 4 5 6 7 8 9
| interface PrintSizeable { func printSize(): Unit }
extend<T> Array<T> <: PrintSizeable { public func printSize() { println("The size is ${this.size}") } }
|
4.3 使用
1 2 3 4
| main() { let a: PrintSizeable = Array<Int64>() a.printSize() // 0 }
|
五 访问规则
5.1 扩展的修饰符
1-扩展成员可使用的修饰符有:static、public、protected(仅限于被扩展类型是 class 类型)、private、mut。
- 使用 private 修饰的成员只能在本扩展内使用,外部不可见。
- 使用 protected 修饰的成员除了能在本包内被访问,对包外的当前 class 子类也可以访问。
- 没有使用 private,protected 或 public 修饰的成员只能在本包内使用。
- 使用 static 修饰的成员,只能通过类型名访问,不能通过实例对象访问。
- 对 struct 类型的扩展可以定义 mut 函数。
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package p1
public open class A {}
extend A { public func f1() {} protected func f2() {} private func f3() {} static func f4() {} }
main() { A.f4() var a = A() a.f1() a.f2() }
|
2-扩展内的成员定义不支持使用 open、override、redef 修饰
1 2 3 4 5 6 7 8 9 10
| class Foo { public open func f() {} static func h() {} }
extend Foo { public override func f() {} // Error public open func g() {} // Error redef static func h() {} // Error }
|
5.2 扩展的孤儿规则
仓颉不允许定义孤儿扩展,指的是既不与接口(包含接口继承链上的所有接口)定义在同一个包中,也不与被扩展类型定义在同一个包中的接口扩展
1 2 3 4 5 6 7 8 9 10 11
| // package a public class Foo {}
// package b public interface Bar {}
// package c import a.Foo import b.Bar
extend Foo <: Bar {} // Error
|
5.3 扩展的访问和遮盖
1 2 3 4 5 6 7 8 9 10
| class A { var v = 0 }
extend A { func f() { print(this.v) // ok print(v) // ok } }
|
5.4 扩展的导入导出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package a
public class Foo {}
extend Foo { public func f() {} }
///////
package b import a.*
extend Foo { public func g() {} }
///////
package c import a.* import b.*
main() { let a = Foo() a.f() // OK a.g() // Error }
|
六 思维导图
七 参考