Files
endorphin-tessera-gui/examples/classes.endor

44 lines
2.4 KiB
Plaintext

// 普通源类继承示例:GUI 点击执行继承的 activate,内部 self.change 再动态分派到 DemoCounter 覆盖。
// 两个 textOf 共享同一模型字段,修改一次业务值会更新两个展示位置。
// 定义业务状态和公共事件入口,Number/String 字段在构造与赋值时按声明契约检查。
class Counter {
// value 是两处 textOf 的读取目标,lastEvent 是第三处绑定的读取目标;它们都属于同一模型。
value: Number
lastEvent: String
// 保存实际事件种类,再通过 self 调用可覆盖的方法;接收者保持具体子类身份。
function activate(self: Counter, event: Event): Unit {
// Button.onClick 派发传入本次 Event;先记录种类,再调用下面的动态业务方法。
self.lastEvent = event.kind
self.change()
}
// 基类默认行为把值置为 10,子类可复用入口并替换这部分策略。
function change(self: Counter): Unit {
// 仅直接使用 Counter 或未覆盖 change 的子类才采用此默认值;本例 DemoCounter 会替换它。
self.value = 10
}
}
// 继承 Counter 的字段与 activate,仅替换 change;构造参数仍按继承字段顺序传入。
class DemoCounter: Counter {
// 覆盖把值设为 12,演示从继承方法内部发起的调用也会选中实际接收者的方法。
function change(self: DemoCounter): Unit {
// 本例从 Counter.activate 的 self.change() 进入这里,self 仍是 model,两个数值绑定一起失效。
self.value = 12
}
}
// 创建唯一模型,之后所有绑定和按钮回调都指向它,无需把 GUI 状态复制到另一份存储。
model = DemoCounter(9, "等待点击")
// 两次调用各创建一个展示对象,但都读取 model.value;不是把初值 9 各自复制成互不关联的计数器。
first = ui.textOf(model, "value", 2)
second = ui.textOf(model, "value", 2)
eventName = ui.textOf(model, "lastEvent")
// 构造按钮只建立对象,下一行 onClick 注册后才拥有修改模型的点击行为。
button = Button("调用继承方法,再分派到覆盖方法")
// 注册绑定方法,运行时将 click 的 Event 传给 activate;最后 Page.render 才把对象树显示出来。
button.onClick(model.activate)
page = Page()
page.render(Column(24, 16, TextBlock("Endor class:继承、self 与动态方法分派", 2), Row(0, 16, first, second), button, eventName))