引言
仓颉语言作为一门现代化的编程语言,提供了完整的面向对象编程支持
1. 类(Class)详解
1.1 类的基本概念
类(class)是面向对象编程中的核心概念,在仓颉中,类与结构体(struct)的主要区别在于:
- 类是引用类型:赋值或传参时传递的是引用,多个变量指向同一个对象
- 结构体是值类型:赋值或传参时进行值拷贝
- 类支持继承:可以创建继承层次结构
- 结构体不支持继承:只能实现接口
1.1.1 基本类定义
cangjie
class Rectangle {
let width: Int64
let height: Int64
public init(width: Int64, height: Int64) {
this.width = width
this.height = height
}
// public 成员函数,必须显式标注返回值类型
public func area(): Int64 {
width * height
}
}
这个例子展示了类的基本结构:
- 使用
class
关键字定义类 - 包含成员变量
width
和height
- 定义构造函数
init
- 包含成员函数
area
1.1.2 抽象类
抽象类使用 abstract
关键字修饰,可以包含抽象函数(没有函数体的函数):
cangjie
abstract class Shape {
public func area(): Int64
public func perimeter(): Int64
public func description(): String {
"A shape with area ${area()} and perimeter ${perimeter()}"
}
}
重要注意点:
- 抽象类中禁止定义
private
的抽象函数 - 不能为抽象类创建实例
- 抽象类的非抽象子类必须实现父类中的所有抽象函数
1.2 类成员详解
1.2.1 成员变量
类的成员变量分为实例成员变量和静态成员变量:
cangjie
class Counter {
// 实例成员变量
var count: Int64 = 0
let maxCount: Int64 = 100
// 静态成员变量
static let defaultMax: Int64 = 50
static var totalInstances: Int64 = 0
public init() {
Counter.totalInstances += 1
}
public func increment(): Unit {
if (count < maxCount) {
count += 1
}
}
public static func getDefaultMax(): Int64 {
defaultMax
}
}
关键特性:
- 实例成员变量通过对象访问:
counter.count
- 静态成员变量通过类名访问:
Counter.defaultMax
- 静态成员变量在静态初始化器中初始化
1.2.2 静态初始化器
静态初始化器用于初始化静态成员变量:
cangjie
class Configuration {
static let appName: String
static let version: String
static let buildNumber: Int64
static init() {
appName = "MyApp"
version = "1.0.0"
buildNumber = 100
}
}
限制条件:
- 一个类中最多只能定义一个静态初始化器
- 必须完成对所有未初始化的静态成员变量的初始化
- 不能被访问修饰符修饰
1.2.3 构造函数
仓颉支持两种构造函数:普通构造函数和主构造函数。
普通构造函数:
cangjie
class Person {
let email: ?String
// 主构造函数
public Person(let name: String, let age: Int64) {
this.email = None<String>
}
// 普通构造函数
public init(name: String, age: Int64, email: String) {
this.name = name
this.age = age
this.email = email
}
// 无参构造函数
public init() {
this.name = "Unknown"
this.age = 0
this.email = None<String>
}
}
主构造函数:
- 函数名与类名相同
- 参数前加
let
或var
可以同时定义成员变量 - 最多只能有一个主构造函数
cangjie
class Point {
// 主构造函数,同时定义成员变量
// public Point(let x: Int64, let y: Int64) {}
// 或者混合使用
public Point(name: String, let x: Int64, let y: Int64) {}
}
构造函数执行顺序:
- 初始化有缺省值的变量
- 调用父类构造函数(如果未显式调用)
- 执行构造函数体内的代码
cangjie
open class Animal {
init() {
println("Animal constructor")
}
}
class Dog <: Animal {
var name = "Default"
init() {
// 这里可以省略super(),调用。如果我们没写,编译器会自动插入一个super的无参调用
// super()
name = "Buddy"
println("Dog constructor")
}
}
// 输出顺序:
// Animal constructor
// Dog constructor
1.2.4 终结器
终结器在对象被垃圾回收时触发,用于释放系统资源:
cangjie
import std.core.LibC
class FileHandler {
var filePath: String
var fileHandle: CString
init(path: String) {
filePath = path
fileHandle = unsafe { LibC.mallocCString("aaaaar") }
}
~init() {
unsafe { LibC.free(fileHandle) }
println("File ${filePath} closed")
}
}
终结器的重要限制:
- 函数名固定为
~init
- 没有参数、返回类型、修饰符
- 不能被显式调用
- 执行时机不确定
- 可能在任意线程上执行
1.2.5 成员函数
成员函数分为实例成员函数和静态成员函数:
cangjie
class MathUtils {
static let cnt: Int = 20
// 实例成员函数
public func add(a: Int64, b: Int64): Int64 {
let cnt = MathUtils.cnt
a + b
}
// 静态成员函数
public static func factorial(n: Int64): Int64 {
if (n <= 1) {
1
} else {
n * factorial( n - 1)
}
}
}
函数访问规则:
- 实例成员函数中能访问静态成员
- 静态成员函数中不能访问实例成员
- 实例成员函数中可以通过
this
访问实例成员
1.3 访问修饰符
仓颉提供四种访问修饰符:
cangjie
package cangjie_blog.a
public open class Example {
public var publicVar: Int64 = 1 // 模块内外均可见
protected var protectedVar: Int64 = 2 // 当前模块及子类可见
internal var internalVar: Int64 = 3 // 仅当前包及子包可见(默认)
private var privateVar: Int64 = 4 // 仅在类定义内可见
public func publicMethod() {}
protected func protectedMethod() {}
internal func internalMethod() {}
private func privateMethod() {}
}
访问级别总结:
private
:类内部可见internal
:包内可见(默认)protected
:模块内及子类可见public
:模块内外均可见
1.4 This 类型
This
类型是类的特殊类型占位符,代表当前类的类型:
cangjie
open class Builder {
func build(): This {
this
}
func chain(): This {
// 返回当前对象,支持链式调用
this
}
}
class StringBuilder <: Builder {
var content: String = ""
func append(str: String): This {
content += str
this
}
}
main() {
let builder = StringBuilder()
let result = builder.append("Hello").append(" World").build()
println("result is StringBuilder ${result is StringBuilder}")
// result 的类型是 StringBuilder,不是 Builder
}
This 类型的特性:
- 只能作为实例成员函数的返回类型
- 支持多态返回类型
- 子类调用时返回类型会被识别为子类类型
1.5 对象创建与使用
1.5.1 创建对象
cangjie
class Car {
var brand: String
var model: String
var year: Int64
// 构造函数也是函数,支持命名参数
public init(brand!: String, model!: String, year!: Int64) {
this.brand = brand
this.model = model
this.year = year
}
public func getInfo(): String {
"${year} ${brand} ${model}"
}
}
main() {
// 创建对象
let car = Car(brand: "Toyota", model: "Camry", year: 2023)
// 访问成员
println(car.brand) // Toyota
println(car.getInfo()) // 2023 Toyota Camry
// 修改成员(需要 var 修饰)
car.year = 2024
println(car.getInfo()) // 2024 Toyota Camry
}
1.5.2 引用类型特性
类作为引用类型,赋值时传递的是引用:
cangjie
class Counter {
var value: Int64 = 0
public func increment() {
value += 1
}
public func getValue(): Int64 {
value
}
}
main() {
let counter1 = Counter()
let counter2 = counter1 // 传递引用,不是拷贝
counter1.increment()
println(counter1.getValue()) // 1
println(counter2.getValue()) // 1,因为指向同一个对象
counter2.increment()
println(counter1.getValue()) // 2
println(counter2.getValue()) // 2
}
1.6 类的继承
1.6.1 基本继承
cangjie
open class Animal {
var name: String
var age: Int64
public init(name: String, age: Int64) {
this.name = name
this.age = age
}
// 允许被重写的方法需要使用open修饰
open public func makeSound(): String {
"Some sound"
}
public func getInfo(): String {
"Name: ${name}, Age: ${age}"
}
}
class Dog <: Animal {
var breed: String
public init(name: String, age: Int64, breed: String) {
super(name, age) // 调用父类构造函数
this.breed = breed
}
public override func makeSound(): String {
"Woof!"
}
public func getBreed(): String {
breed
}
}
class Cat <: Animal {
var color: String
public init(name: String, age: Int64, color: String) {
super(name, age)
this.color = color
}
public override func makeSound(): String {
"Meow!"
}
}
继承规则:
- 使用
<:
表示继承关系 - 只有
open
修饰的类才能被继承 - 抽象类总是可被继承
- 类只支持单继承
1.6.2 构造函数调用
子类构造函数必须调用父类构造函数:
cangjie
open class Base {
var value: Int64
public init(value: Int64) {
this.value = value
}
public init() {
this.value = 0
}
}
class Derived <: Base {
var name: String
public init(value: Int64, name: String) {
super(value) // 显式调用父类构造函数
this.name = name
}
public init(name: String) {
super() // 调用父类无参构造函数
this.name = name
}
public init() {
super() // 调用父类无参构造函数
this.name = "Default"
}
}
构造函数调用规则:
- 必须使用
super(args)
调用父类构造函数 - 或使用
this(args)
调用本类其他构造函数 - 调用必须在构造函数体的第一个表达式处
- 如果未显式调用,编译器会自动插入
super()
1.6.3 函数覆盖
子类可以覆盖父类的 open
函数:
cangjie
open class Shape {
public open func area(): Int64 {
0
}
public open func perimeter(): Int64 {
0
}
}
class Rectangle <: Shape {
var width: Int64
var height: Int64
public init(width: Int64, height: Int64) {
this.width = width
this.height = height
}
public override func area(): Int64 {
width * height
}
public override func perimeter(): Int64 {
2 * (width + height)
}
}
class Circle <: Shape {
var radius: Int64
public init(radius: Int64) {
this.radius = radius
}
public override func area(): Int64 {
// 简化的圆形面积计算
3 * radius * radius
}
public override func perimeter(): Int64 {
2 * 3 * radius
}
}
覆盖规则:
- 父类函数必须使用
open
修饰 - 子类函数使用
override
修饰(可选) - 函数签名必须完全匹配
- 支持动态派发
1.6.4 静态函数重定义
子类可以重定义父类的静态函数:
cangjie
open class Base {
public static func getType(): String {
"Base"
}
public static func getVersion(): String {
"1.0"
}
}
class Derived <: Base {
public static redef func getType(): String {
"Derived"
}
// 不重定义 getVersion,继承父类实现
}
main() {
println(Base.getType()) // Base
println(Base.getVersion()) // 1.0
println(Derived.getType()) // Derived
println(Derived.getVersion()) // 1.0
}
重定义规则:
- 使用
redef
修饰符(可选) - 静态函数不支持动态派发
- 根据类类型决定调用版本
1.6.5 继承性修饰符
cangjie
// 可继承的类
public open class OpenClass {}
// 不可继承的类(默认)
class FinalClass {}
// 抽象类(总是可被继承)
// 默认修饰符internal
abstract class AbstractClass {
public func abstractMethod(): Unit
}
// 密封抽象类(只能在本包被继承)
abstract sealed class SealedAbstractClass {
public func abstractMethod(): Unit
}
// 继承示例
class SubClass <: OpenClass {} // OK
class SubAbstract <: AbstractClass { // OK
public func abstractMethod(): Unit {
}
}
class SubSealed <: SealedAbstractClass { // OK(同包内)
public func abstractMethod(): Unit {}
}
// 这些继承会报错
// class SubFinal <: FinalClass {} // Error
// class SubOpen <: SubClass {} // Error(SubClass 不是 open 的)
2. 接口(Interface)详解
2.1 接口基本概念
接口定义抽象类型,不包含数据,但可以定义类型的行为:
cangjie
interface Drawable {
func draw(): Unit
func getArea(): Int64
}
interface Movable {
func move(x: Int64, y: Int64): Unit
func getPosition(): (Int64, Int64)
}
接口特性:
- 成员都是抽象的(除非有默认实现)
- 实现类型必须提供所有成员的实现
- 支持多重实现
- 可以继承其他接口
2.2 接口成员
2.2.1 实例成员
cangjie
interface Vehicle {
func start(): Unit
func stop(): Unit
func getSpeed(): Int64
func setSpeed(speed: Int64): Unit
}
class Car <: Vehicle {
private var speed: Int64 = 0
private var isRunning: Bool = false
public func start(): Unit {
isRunning = true
println("Car started")
}
public func stop(): Unit {
isRunning = false
speed = 0
println("Car stopped")
}
public func getSpeed(): Int64 {
speed
}
public func setSpeed(speed: Int64): Unit {
if (isRunning) {
this.speed = speed
}
}
}
2.2.2 静态成员
cangjie
interface Factory {
static func create(): Factory
static func getType(): String
}
class CarFactory <: Factory {
public static func create(): CarFactory {
CarFactory()
}
public static func getType(): String {
"CarFactory"
}
}
class BikeFactory <: Factory {
public static func create(): BikeFactory {
BikeFactory()
}
public static func getType(): String {
"BikeFactory"
}
}
2.2.3 默认实现
接口可以提供默认实现:
cangjie
interface Logger {
func log(message: String): Unit {
println("[${getTimestamp()}] ${message}")
}
func getTimestamp(): String
func logError(error: String): Unit {
log("ERROR: ${error}")
}
}
class ConsoleLogger <: Logger {
public func getTimestamp(): String {
// 简化的时间戳
"2024-01-01 12:00:00"
}
// 继承 log 和 logError 的默认实现
}
class FileLogger <: Logger {
public func getTimestamp(): String {
"2024-01-01 12:00:00"
}
// 覆盖默认实现
public override func log(message: String): Unit {
println("FILE: ${message}")
}
}
2.3 接口实现
2.3.1 单接口实现
cangjie
interface Printable {
func print(): Unit
func getContent(): String
}
class Document <: Printable {
private var content: String
public init(content: String) {
this.content = content
}
public func print(): Unit {
println("Printing: ${content}")
}
public func getContent(): String {
content
}
}
2.3.2 多接口实现
使用 &
分隔多个接口:
cangjie
interface Readable {
func read(): String
}
interface Writable {
func write(content: String): Unit
}
interface ReadWriteable <: Readable & Writable {
func clear(): Unit
}
class TextFile <: ReadWriteable {
private var content: String = ""
public func read(): String {
content
}
public func write(content: String): Unit {
this.content = content
}
public func clear(): Unit {
content = ""
}
}
2.3.3 接口继承
cangjie
interface Animal {
func makeSound(): String
}
interface Pet <: Animal {
func getName(): String
func play(): Unit
}
interface Dog <: Pet {
func wagTail(): Unit
}
class GoldenRetriever <: Dog {
private var name: String
public init(name: String) {
this.name = name
}
public func makeSound(): String {
"Woof!"
}
public func getName(): String {
name
}
public func play(): Unit {
println("${name} is playing fetch")
}
public func wagTail(): Unit {
println("${name} is wagging tail")
}
}
2.4 接口冲突解决
当多个接口有相同成员的默认实现时,需要显式实现:
cangjie
interface Logger {
func log(message: String): Unit {
println("Logger: ${message}")
}
}
interface Printer {
func log(message: String): Unit {
println("Printer: ${message}")
}
}
class Device <: Logger & Printer {
// 必须显式实现,避免冲突
public func log(message: String): Unit {
println("Device: ${message}")
}
}
2.5 Any 类型
Any
是所有类型的基接口:
cangjie
// 所有类型都默认实现 Any
main() {
var any: Any = 42
any = "Hello"
any = true
any = 3.14
}
3. 属性(Properties)详解
3.1 属性基本概念
属性提供 getter 和可选的 setter 来间接访问值:
cangjie
class BankAccount {
private var balance: Int64 = 0
// 只读属性
public prop currentBalance: Int64 {
get() {
balance
}
}
// 读写属性
public mut prop accountBalance: Int64 {
get() {
balance
}
// set这里不需要写类型,也不让写类型。由编译器自动推断
set(value) {
if (value >= 0) {
balance = value
}
}
}
// 计算属性
public prop isOverdrawn: Bool {
get() {
balance < 0
}
}
}
3.2 属性类型
3.2.1 只读属性
cangjie
class Circle {
private let radius: Int64
public init(radius: Int64) {
this.radius = radius
}
public prop diameter: Int64 {
get() {
radius * 2
}
}
public prop circumference: Int64 {
get() {
2 * 3 * radius // 简化的圆周率
}
}
}
3.2.2 读写属性
cangjie
class Temperature {
private var celsius: Float64 = 0.0
public mut prop temperature: Float64 {
get() {
celsius
}
set(value) {
celsius = value
}
}
public mut prop fahrenheit: Float64 {
get() {
celsius * 9.0 / 5.0 + 32.0
}
set(value) {
celsius = (value - 32.0) * 5.0 / 9.0
}
}
}
3.3 静态属性
cangjie
import std.collection.HashMap
class Configuration {
private static var instance: ?Configuration = None<Configuration>
private var settings: HashMap<String, String> = HashMap<String, String>()
public static prop shared: Configuration {
get() {
// 使用标准库ifNone函数
ifNone(instance) {
instance = Configuration()
}
instance.getOrThrow()
}
}
public mut prop serverUrl: String {
get() {
settings.get("serverUrl") ?? "localhost:8080"
}
set(value) {
settings.add("serverUrl", value)
}
}
}
3.4 属性继承与覆盖
cangjie
open class Base {
public open prop value: Int64 {
get() {
0
}
}
public open mut prop mutableValue: Int64 {
get() {
0
}
set(v) {
// 基类实现
}
}
}
class Derived <: Base {
private var actualValue: Int64 = 42
public override prop value: Int64 {
get() {
actualValue
}
}
public override mut prop mutableValue: Int64 {
get() {
actualValue
}
set(v) {
actualValue = v
}
}
}
4. 子类型关系
4.1 继承带来的子类型关系
cangjie
open class Animal {}
class Dog <: Animal {}
class Cat <: Animal {}
// Dog 和 Cat 都是 Animal 的子类型
func feed(animal: Animal): Unit {
println("Feeding animal")
}
main() {
let dog = Dog()
let cat = Cat()
feed(dog) // OK: Dog <: Animal
feed(cat) // OK: Cat <: Animal
}
4.2 接口实现带来的子类型关系
cangjie
interface Movable {
func move(): Unit
}
interface Eatable {
func eat(): Unit
}
class Bird <: Movable & Eatable {
public func move(): Unit {
println("Bird is flying")
}
public func eat(): Unit {
println("Bird is eating")
}
}
// Bird 是 Movable 和 Eatable 的子类型
func processMovable(movable: Movable): Unit {
movable.move()
}
func processEatable(eatable: Eatable): Unit {
eatable.eat()
}
main() {
let bird = Bird()
processMovable(bird) // OK: Bird <: Movable
processEatable(bird) // OK: Bird <: Eatable
}
4.3 元组类型的子类型关系
cangjie
open class Base {}
class Derived <: Base {}
// (Derived, Derived) <: (Base, Base)
let tuple1: (Base, Base) = (Derived(), Derived())
4.4 函数类型的子类型关系
cangjie
open class Base {}
class Derived <: Base {}
// 如果 Derived <: Base,那么 (Base) -> Derived <: (Derived) -> Base
func processBase(base: Base): Derived {
Derived()
}
func processDerived(derived: Derived): Base {
derived
}
// processBase 的类型是 processDerived 的子类型
5. 类型转换
5.1 数值类型转换
cangjie
main() {
let int8Value: Int8 = 100
let int16Value: Int16 = 1000
let float32Value: Float32 = 3.14
// 显式类型转换
let convertedInt16 = Int16(int8Value)
let convertedInt8 = Int8(int16Value)
let convertedFloat64 = Float64(float32Value)
println("Int8 to Int16: ${convertedInt16}")
println("Int16 to Int8: ${convertedInt8}")
println("Float32 to Float64: ${convertedFloat64}")
}
5.2 字符类型转换
cangjie
main() {
let char: Rune = 'A'
let unicodeValue = UInt32(char)
let number: UInt32 = 66
let charFromNumber = Rune(number)
println("Character '${char}' has Unicode value: ${unicodeValue}")
println("Unicode value ${number} represents character: '${charFromNumber}'")
}
5.3 类型检查与转换
5.3.1 is 操作符
cangjie
open class Shape {}
class Circle <: Shape {}
class Rectangle <: Shape {}
main() {
let shapes: Array<Shape> = [Circle(), Rectangle(), Circle()]
for (shape in shapes) {
// 这里可以修改为match
if (shape is Circle) {
println("Found a circle")
} else if (shape is Rectangle) {
println("Found a rectangle")
} else {
println("Found a shape")
}
}
}
5.3.2 as 操作符
cangjie
open class Animal {}
class Dog <: Animal {}
class Cat <: Animal {}
func processDog(dog: Dog): Unit {
println("Processing dog")
}
main() {
let animals: Array<Animal> = [Dog(), Cat(), Dog()]
for (animal in animals) {
// 尝试转换为 Dog 类型
let dogOption = animal as Dog
match (dogOption) {
case Some(dog) => processDog(dog)
case None => println("Not a dog")
}
}
}
6. 实际应用场景
6.1 设计模式实现
6.1.1 策略模式
cangjie
interface PaymentStrategy {
func pay(amount: Int64): Unit
}
class CreditCardPayment <: PaymentStrategy {
private var cardNumber: String
public init(cardNumber: String) {
this.cardNumber = cardNumber
}
public func pay(amount: Int64): Unit {
println("Paid ${amount} using credit card ending in ${cardNumber}")
}
}
class PayPalPayment <: PaymentStrategy {
private var email: String
public init(email: String) {
this.email = email
}
public func pay(amount: Int64): Unit {
println("Paid ${amount} using PayPal account ${email}")
}
}
class ShoppingCart {
private let items: ArrayList<String> = ArrayList()
private var paymentStrategy: ?PaymentStrategy = None<PaymentStrategy>
public func addItem(item: String): Unit {
items.add(item)
}
public func setPaymentStrategy(strategy: PaymentStrategy): Unit {
paymentStrategy = strategy
}
public func checkout(): Unit {
let total = items.size * 10 // 假设每件商品10元
if (let Some(strategy) <- paymentStrategy) {
strategy.pay(total)
} else {
println("No payment strategy set")
}
}
}
main() {
let s = ShoppingCart()
s.addItem("one piece")
s.setPaymentStrategy(CreditCardPayment("12345"))
s.checkout()
s.setPaymentStrategy(PayPalPayment("67890"))
s.checkout()
}
6.1.2 工厂模式
cangjie
interface Vehicle {
func start(): Unit
func stop(): Unit
}
class Car <: Vehicle {
public func start(): Unit {
println("Car started")
}
public func stop(): Unit {
println("Car stopped")
}
}
class Motorcycle <: Vehicle {
public func start(): Unit {
println("Motorcycle started")
}
public func stop(): Unit {
println("Motorcycle stopped")
}
}
interface VehicleFactory {
static func createVehicle(): Vehicle
}
class CarFactory <: VehicleFactory {
public static func createVehicle(): Vehicle {
Car()
}
}
class MotorcycleFactory <: VehicleFactory {
public static func createVehicle(): Vehicle {
Motorcycle()
}
}
// 由于仓颉中没给出元类型的语法。所以以下方式无法实现。
// 正确的语法应该类似 VehicleFactory.This这样的语法
func createAndUseVehicle(factory: VehicleFactory): Unit {
// object cannot access static member 'createVehicle'
let vehicle = factory.createVehicle()
vehicle.start()
vehicle.stop()
}
6.2 数据模型设计
cangjie
import std.time.DateTime
interface Identifiable {
func getId(): String
}
interface Timestamped {
func getCreatedAt(): Int64
func getUpdatedAt(): Int64
}
open class BaseEntity <: Identifiable & Timestamped {
private let id: String
private let createdAt: Int64
private var updatedAt: Int64
public init(id: String) {
this.id = id
this.createdAt = DateTime.now().nanosecond
this.updatedAt = this.createdAt
}
public func getId(): String {
id
}
public func getCreatedAt(): Int64 {
createdAt
}
public func getUpdatedAt(): Int64 {
updatedAt
}
protected func updateTimestamp(): Unit {
updatedAt = getCurrentTimestamp()
}
private func getCurrentTimestamp(): Int64 {
// 简化的时间戳获取
1640995200 // 2022-01-01 00:00:00
}
}
class User <: BaseEntity {
private var username: String
private var email: String
public init(id: String, username: String, email: String) {
super(id)
this.username = username
this.email = email
}
public func getUsername(): String {
username
}
public func getEmail(): String {
email
}
public func updateEmail(email: String): Unit {
this.email = email
updateTimestamp()
}
}
class Post <: BaseEntity {
private var title: String
private var content: String
private var authorId: String
public init(id: String, title: String, content: String, authorId: String) {
super(id)
this.title = title
this.content = content
this.authorId = authorId
}
public func getTitle(): String {
title
}
public func getContent(): String {
content
}
public func getAuthorId(): String {
authorId
}
public func updateContent(content: String): Unit {
this.content = content
updateTimestamp()
}
}
7. 最佳实践与注意事项
7.1 类设计原则
- 单一职责原则:每个类应该只有一个职责
- 开闭原则:对扩展开放,对修改关闭
- 里氏替换原则:子类应该能够替换父类
- 接口隔离原则:接口应该小而专注
- 依赖倒置原则:依赖抽象而不是具体实现
7.2 性能考虑
cangjie
class OptimizedProcessor {
private static let sharedBuffer: ArrayList<Int64> = ArrayList()
public static func processBatch(items: Array<Int64>): Array<Int64> {
// 重用缓冲区而不是每次都创建新的
sharedBuffer.clear()
for (item in items) {
sharedBuffer.add(item * 2)
}
sharedBuffer.clone().toArray()
}
}
// 使用对象池模式
class ObjectPool<T> where T <: Equatable<T> {
private var available: ArrayList<T> = ArrayList()
private var inUse: ArrayList<T> = ArrayList()
public func acquire(): ?T {
if (available.isEmpty()) {
None
} else {
let obj = available.remove(at: 0)
inUse.add(obj)
obj
}
}
public func release(obj: T): Unit {
inUse.removeIf {t => t == obj}
available.add(obj)
}
}
7.3 错误处理
cangjie
interface Result<T, E> {
func isSuccess(): Bool
func isError(): Bool
func getValue(): ?T
func getError(): ?E
}
class Success<T, E> <: Result<T, E> {
private var value: T
public init(value: T) {
this.value = value
}
public func isSuccess(): Bool {
true
}
public func isError(): Bool {
false
}
public func getValue(): ?T {
value
}
public func getError(): ?E {
None<E>
}
}
class Error<T, E> <: Result<T, E> {
private var error: E
public init(error: E) {
this.error = error
}
public func isSuccess(): Bool {
false
}
public func isError(): Bool {
true
}
public func getValue(): ?T {
None<T>
}
public func getError(): ?E {
error
}
}