46 lines
2.7 KiB
Plaintext
46 lines
2.7 KiB
Plaintext
// 方法覆盖遵守参数可更宽、返回可更具体的规则。
|
||
// WideRect 复用基类原生测量后返回 Sized 子类结果;事件改变基础 width 后按同一路径重测。
|
||
// MeasureResult 的名义子类,不增加字段,用于演示返回值协变。
|
||
class Sized: MeasureResult {}
|
||
// 用源方法显式委托原生测量,保留 Mount/Constraints 的基类契约。
|
||
class BaseRect: RectBlock {
|
||
// 原生方法按给定出现位置与约束测量,不把几何存进共享对象。
|
||
function measure(self: BaseRect, mount: Mount, constraints: Constraints): MeasureResult {
|
||
// 由 WideRect.measure 显式调用此实现,再委托 RectBlock 原生测量;传递的仍是当前出现与当前约束。
|
||
return RectBlock.measure(self, mount, constraints)
|
||
}
|
||
}
|
||
// 覆盖参数放宽为 Object,返回缩窄为 Sized;不能反过来缩窄参数或放宽返回。
|
||
class WideRect: BaseRect {
|
||
// 调用基类后复制测量数值到新的 Sized;新结果仍满足 MeasureResult 协议。
|
||
function measure(self: WideRect, mount: Object, constraints: Object): Sized {
|
||
// 宿主布局驱动仍传入 Mount/Constraints;Object 注解只放宽本覆盖的参数检查,不改变实际输入对象。
|
||
// 若手工传入其他 Object,下一行委托 BaseRect.measure 仍检查其较窄的 Mount/Constraints 契约,不保证调用成功。
|
||
measured = BaseRect.measure(self, mount, constraints)
|
||
// 拷贝的是本轮测量结果的两个数值,不复制业务矩形或 Mount;返回新结果供宿主校验。
|
||
return Sized(measured.width, measured.height)
|
||
}
|
||
}
|
||
// 保存具体 WideRect 和计数器,使宽度修改和点击次数同时作为业务变化传播。
|
||
class Actions {
|
||
rect: WideRect
|
||
count: Object
|
||
// 先改 width 再递增计数,新的布局刷新会使用上述动态测量覆盖。
|
||
function widen(self: Actions): Unit {
|
||
// Button.onClick 调用零参绑定方法;width 写入令依赖该原生尺寸的测量失效,count 驱动另一文字绑定。
|
||
self.rect.width = 260
|
||
self.count.increment()
|
||
}
|
||
}
|
||
// 初始矩形宽 180;按钮事件完成后应变为 260,同时文字显示计数。
|
||
rect = WideRect(180, 60, 8, "#ED6A5A")
|
||
count = ui.state(0)
|
||
actions = Actions(rect, count)
|
||
// 所有点击都操作同一个 rect/count;重复设 width=260 不继续增加宽度,但 increment 每次都会增加计数。
|
||
button = Button("扩大矩形")
|
||
button.onClick(actions.widen)
|
||
root = Column(24, 16, TextBlock("参数可以更宽,返回类型可以更具体", 2), rect, button, ui.textOf(count, "value"))
|
||
page = Page()
|
||
page.title = "方法覆写契约"
|
||
page.render(root)
|