diff options
Diffstat (limited to 'doc/docs/zh/doc/objects/object-oriented-programming.md')
| -rw-r--r-- | doc/docs/zh/doc/objects/object-oriented-programming.md | 550 |
1 files changed, 550 insertions, 0 deletions
diff --git a/doc/docs/zh/doc/objects/object-oriented-programming.md b/doc/docs/zh/doc/objects/object-oriented-programming.md new file mode 100644 index 0000000..9eb94d8 --- /dev/null +++ b/doc/docs/zh/doc/objects/object-oriented-programming.md | |||
| @@ -0,0 +1,550 @@ | |||
| 1 | # 面向对象编程 | ||
| 2 | |||
| 3 |   在以下的示例中,月之脚本生成的 Lua 代码可能看起来会很复杂。所以最好主要关注月之脚本代码层面的意义,然后如果你想知道关于面向对象功能的实现细节,再查看 Lua 代码。 | ||
| 4 | |||
| 5 |   一个简单的类: | ||
| 6 | |||
| 7 | ```yuescript | ||
| 8 | class Inventory | ||
| 9 | new: => | ||
| 10 | @items = {} | ||
| 11 | |||
| 12 | add_item: (name) => | ||
| 13 | if @items[name] | ||
| 14 | @items[name] += 1 | ||
| 15 | else | ||
| 16 | @items[name] = 1 | ||
| 17 | ``` | ||
| 18 | <YueDisplay> | ||
| 19 | |||
| 20 | ```yue | ||
| 21 | class Inventory | ||
| 22 | new: => | ||
| 23 | @items = {} | ||
| 24 | |||
| 25 | add_item: (name) => | ||
| 26 | if @items[name] | ||
| 27 | @items[name] += 1 | ||
| 28 | else | ||
| 29 | @items[name] = 1 | ||
| 30 | ``` | ||
| 31 | |||
| 32 | </YueDisplay> | ||
| 33 | |||
| 34 |   在月之脚本中采用面向对象的编程方式时,通常会使用类声明语句结合 Lua 表格字面量来做类定义。这个类的定义包含了它的所有方法和属性。在这种结构中,键名为 “new” 的成员扮演了一个重要的角色,是作为构造函数来使用。 | ||
| 35 | |||
| 36 |   值得注意的是,类中的方法都采用了粗箭头函数语法。当在类的实例上调用方法时,该实例会自动作为第一个参数被传入,因此粗箭头函数用于生成一个名为 “self” 的参数。 | ||
| 37 | |||
| 38 |   此外,“@” 前缀在变量名上起到了简化作用,代表 “self”。例如,`@items` 就等同于 `self.items`。 | ||
| 39 | |||
| 40 |   为了创建类的一个新实例,可以将类名当作一个函数来调用,这样就可以生成并返回一个新的实例。 | ||
| 41 | |||
| 42 | ```yuescript | ||
| 43 | inv = Inventory! | ||
| 44 | inv\add_item "t-shirt" | ||
| 45 | inv\add_item "pants" | ||
| 46 | ``` | ||
| 47 | <YueDisplay> | ||
| 48 | |||
| 49 | |||
| 50 | ```yue | ||
| 51 | inv = Inventory! | ||
| 52 | inv\add_item "t-shirt" | ||
| 53 | inv\add_item "pants" | ||
| 54 | ``` | ||
| 55 | |||
| 56 | </YueDisplay> | ||
| 57 | |||
| 58 |   在月之脚本的类中,由于需要将类的实例作为参数传入到调用的方法中,因此使用了 **\\** 操作符做类的成员函数调用。 | ||
| 59 | |||
| 60 |   需要特别注意的是,类的所有属性在其实例之间是共享的。这对于函数类型的成员属性通常不会造成问题,但对于其他类型的属性,可能会导致意外的结果。 | ||
| 61 | |||
| 62 |   例如,在下面的示例中,clothes 属性在所有实例之间共享。因此,对这个属性在一个实例中的修改,将会影响到其他所有实例。 | ||
| 63 | |||
| 64 | ```yuescript | ||
| 65 | class Person | ||
| 66 | clothes: [] | ||
| 67 | give_item: (name) => | ||
| 68 | table.insert @clothes, name | ||
| 69 | |||
| 70 | a = Person! | ||
| 71 | b = Person! | ||
| 72 | |||
| 73 | a\give_item "pants" | ||
| 74 | b\give_item "shirt" | ||
| 75 | |||
| 76 | -- 会同时打印出裤子和衬衫 | ||
| 77 | print item for item in *a.clothes | ||
| 78 | ``` | ||
| 79 | <YueDisplay> | ||
| 80 | |||
| 81 | ```yue | ||
| 82 | class Person | ||
| 83 | clothes: [] | ||
| 84 | give_item: (name) => | ||
| 85 | table.insert @clothes, name | ||
| 86 | |||
| 87 | a = Person! | ||
| 88 | b = Person! | ||
| 89 | |||
| 90 | a\give_item "pants" | ||
| 91 | b\give_item "shirt" | ||
| 92 | |||
| 93 | -- 会同时打印出裤子和衬衫 | ||
| 94 | print item for item in *a.clothes | ||
| 95 | ``` | ||
| 96 | |||
| 97 | </YueDisplay> | ||
| 98 | |||
| 99 |   避免这个问题的正确方法是在构造函数中创建对象的可变状态: | ||
| 100 | |||
| 101 | ```yuescript | ||
| 102 | class Person | ||
| 103 | new: => | ||
| 104 | @clothes = [] | ||
| 105 | ``` | ||
| 106 | <YueDisplay> | ||
| 107 | |||
| 108 | ```yue | ||
| 109 | class Person | ||
| 110 | new: => | ||
| 111 | @clothes = [] | ||
| 112 | ``` | ||
| 113 | |||
| 114 | </YueDisplay> | ||
| 115 | |||
| 116 | ## 继承 | ||
| 117 | |||
| 118 |   `extends` 关键字可以在类声明中使用,以继承另一个类的属性和方法。 | ||
| 119 | |||
| 120 | ```yuescript | ||
| 121 | class BackPack extends Inventory | ||
| 122 | size: 10 | ||
| 123 | add_item: (name) => | ||
| 124 | if #@items > size then error "背包已满" | ||
| 125 | super name | ||
| 126 | ``` | ||
| 127 | <YueDisplay> | ||
| 128 | |||
| 129 | ```yue | ||
| 130 | class BackPack extends Inventory | ||
| 131 | size: 10 | ||
| 132 | add_item: (name) => | ||
| 133 | if #@items > size then error "背包已满" | ||
| 134 | super name | ||
| 135 | ``` | ||
| 136 | |||
| 137 | </YueDisplay> | ||
| 138 | |||
| 139 |   在这一部分,我们对月之脚本中的 `Inventory` 类进行了扩展,加入了对可以携带物品数量的限制。 | ||
| 140 | |||
| 141 |   在这个特定的例子中,子类并没有定义自己的构造函数。因此,当创建一个新的实例时,系统会默认调用父类的构造函数。但如果我们在子类中定义了构造函数,我们可以利用 `super` 方法来调用并执行父类的构造函数。 | ||
| 142 | |||
| 143 |   此外,当一个类继承自另一个类时,它会尝试调用父类上的 `__inherited` 方法(如果这个方法存在的话),以此来向父类发送通知。这个 `__inherited` 函数接受两个参数:被继承的父类和继承的子类。 | ||
| 144 | |||
| 145 | ```yuescript | ||
| 146 | class Shelf | ||
| 147 | @__inherited: (child) => | ||
| 148 | print @__name, "被", child.__name, "继承" | ||
| 149 | |||
| 150 | -- 将打印: Shelf 被 Cupboard 继承 | ||
| 151 | class Cupboard extends Shelf | ||
| 152 | ``` | ||
| 153 | <YueDisplay> | ||
| 154 | |||
| 155 | ```yue | ||
| 156 | class Shelf | ||
| 157 | @__inherited: (child) => | ||
| 158 | print @__name, "被", child.__name, "继承" | ||
| 159 | |||
| 160 | -- 将打印: Shelf 被 Cupboard 继承 | ||
| 161 | class Cupboard extends Shelf | ||
| 162 | ``` | ||
| 163 | |||
| 164 | </YueDisplay> | ||
| 165 | |||
| 166 | ## super 关键字 | ||
| 167 | |||
| 168 |   `super` 是一个特别的关键字,它有两种不同的使用方式:既可以当作一个对象来看待,也可以像调用函数那样使用。它仅在类的内部使用时具有特殊的功能。 | ||
| 169 | |||
| 170 |   当 `super` 被作为一个函数调用时,它将调用父类中与之同名的函数。此时,当前的 `self` 会自动作为第一个参数传递,正如上面提到的继承示例所展示的那样。 | ||
| 171 | |||
| 172 |   在将 `super` 当作普通值使用时,它实际上是对父类对象的引用。通过这种方式,我们可以访问父类中可能被子类覆盖的值,就像访问任何普通对象一样。 | ||
| 173 | |||
| 174 |   此外,当使用 `\` 操作符与 `super` 一起使用时,`self`将被插入为第一个参数,而不是使用 `super` 本身的值。而在使用`.`操作符来检索函数时,则会返回父类中的原始函数。 | ||
| 175 | |||
| 176 |   下面是一些使用 `super` 的不同方法的示例: | ||
| 177 | |||
| 178 | ```yuescript | ||
| 179 | class MyClass extends ParentClass | ||
| 180 | a_method: => | ||
| 181 | -- 以下效果相同: | ||
| 182 | super "你好", "世界" | ||
| 183 | super\a_method "你好", "世界" | ||
| 184 | super.a_method self, "你好", "世界" | ||
| 185 | |||
| 186 | -- super 作为值等于父类: | ||
| 187 | assert super == ParentClass | ||
| 188 | ``` | ||
| 189 | <YueDisplay> | ||
| 190 | |||
| 191 | ```yue | ||
| 192 | class MyClass extends ParentClass | ||
| 193 | a_method: => | ||
| 194 | -- 以下效果相同: | ||
| 195 | super "你好", "世界" | ||
| 196 | super\a_method "你好", "世界" | ||
| 197 | super.a_method self, "你好", "世界" | ||
| 198 | |||
| 199 | -- super 作为值等于父类: | ||
| 200 | assert super == ParentClass | ||
| 201 | ``` | ||
| 202 | |||
| 203 | </YueDisplay> | ||
| 204 | |||
| 205 |   **super** 也可以用在函数存根的左侧。唯一的主要区别是,生成的函数不是绑定到 super 的值,而是绑定到 self。 | ||
| 206 | |||
| 207 | ## 类型 | ||
| 208 | |||
| 209 |   每个类的实例都带有它的类型。这存储在特殊的 \_\_class 属性中。此属性会保存类对象。类对象是我们用来构建新实例的对象。我们还可以索引类对象以检索类方法和属性。 | ||
| 210 | |||
| 211 | ```yuescript | ||
| 212 | b = BackPack! | ||
| 213 | assert b.__class == BackPack | ||
| 214 | |||
| 215 | print BackPack.size -- 打印 10 | ||
| 216 | ``` | ||
| 217 | <YueDisplay> | ||
| 218 | |||
| 219 | ```yue | ||
| 220 | b = BackPack! | ||
| 221 | assert b.__class == BackPack | ||
| 222 | |||
| 223 | print BackPack.size -- 打印 10 | ||
| 224 | ``` | ||
| 225 | |||
| 226 | </YueDisplay> | ||
| 227 | |||
| 228 | ## 类对象 | ||
| 229 | |||
| 230 |   在月之脚本中,当我们编写类的定义语句时,实际上是在创建一个类对象。这个类对象被保存在一个与该类同名的变量中。 | ||
| 231 | |||
| 232 |   类对象具有函数的特性,可以被调用来创建新的实例。这正是我们在之前示例中所展示的创建类实例的方式。 | ||
| 233 | |||
| 234 |   一个类由两个表构成:类表本身和一个基表。基表作为所有实例的元表。在类声明中列出的所有属性都存放在基表中。 | ||
| 235 | |||
| 236 |   如果在类对象的元表中找不到某个属性,系统会从基表中检索该属性。这就意味着我们可以直接从类本身访问到其方法和属性。 | ||
| 237 | |||
| 238 |   需要特别注意的是,对类对象的赋值并不会影响到基表,因此这不是向实例添加新方法的正确方式。相反,需要直接修改基表。关于这点,可以参考下面的 “__base” 字段。 | ||
| 239 | |||
| 240 |   此外,类对象包含几个特殊的属性:当类被声明时,类的名称会作为一个字符串存储在类对象的 “__name” 字段中。 | ||
| 241 | |||
| 242 | ```yuescript | ||
| 243 | print BackPack.__name -- 打印 Backpack | ||
| 244 | ``` | ||
| 245 | <YueDisplay> | ||
| 246 | |||
| 247 | ```yue | ||
| 248 | print BackPack.__name -- 打印 Backpack | ||
| 249 | ``` | ||
| 250 | |||
| 251 | </YueDisplay> | ||
| 252 | |||
| 253 |   基础对象被保存在一个名为 `__base` 的特殊表中。我们可以编辑这个表,以便为那些已经创建出来的实例和还未创建的实例增加新的功能。 | ||
| 254 | |||
| 255 |   另外,如果一个类是从另一个类派生而来的,那么其父类对象则会被存储在名为 `__parent` 的地方。这种机制允许在类之间实现继承和功能扩展。 | ||
| 256 | |||
| 257 | ## 类变量 | ||
| 258 | |||
| 259 |   我们可以直接在类对象中创建变量,而不是在类的基对象中,通过在类声明中的属性名前使用 @。 | ||
| 260 | |||
| 261 | ```yuescript | ||
| 262 | class Things | ||
| 263 | @some_func: => print "Hello from", @__name | ||
| 264 | |||
| 265 | Things\some_func! | ||
| 266 | |||
| 267 | -- 类变量在实例中不可见 | ||
| 268 | assert Things().some_func == nil | ||
| 269 | ``` | ||
| 270 | <YueDisplay> | ||
| 271 | |||
| 272 | ```yue | ||
| 273 | class Things | ||
| 274 | @some_func: => print "Hello from", @__name | ||
| 275 | |||
| 276 | Things\some_func! | ||
| 277 | |||
| 278 | -- 类变量在实例中不可见 | ||
| 279 | assert Things().some_func == nil | ||
| 280 | ``` | ||
| 281 | |||
| 282 | </YueDisplay> | ||
| 283 | |||
| 284 |   在表达式中,我们可以使用 @@ 来访问存储在 `self.__class` 中的值。因此,`@@hello` 是 `self.__class.hello` 的简写。 | ||
| 285 | |||
| 286 | ```yuescript | ||
| 287 | class Counter | ||
| 288 | @count: 0 | ||
| 289 | |||
| 290 | new: => | ||
| 291 | @@count += 1 | ||
| 292 | |||
| 293 | Counter! | ||
| 294 | Counter! | ||
| 295 | |||
| 296 | print Counter.count -- 输出 2 | ||
| 297 | ``` | ||
| 298 | <YueDisplay> | ||
| 299 | |||
| 300 | ```yue | ||
| 301 | class Counter | ||
| 302 | @count: 0 | ||
| 303 | |||
| 304 | new: => | ||
| 305 | @@count += 1 | ||
| 306 | |||
| 307 | Counter! | ||
| 308 | Counter! | ||
| 309 | |||
| 310 | print Counter.count -- 输出 2 | ||
| 311 | ``` | ||
| 312 | |||
| 313 | </YueDisplay> | ||
| 314 | |||
| 315 |   @@ 的调用语义与 @ 类似。调用 @@ 时,会使用 Lua 的冒号语法将类作为第一个参数传入。 | ||
| 316 | |||
| 317 | ```yuescript | ||
| 318 | @@hello 1,2,3,4 | ||
| 319 | ``` | ||
| 320 | <YueDisplay> | ||
| 321 | |||
| 322 | ```yue | ||
| 323 | @@hello 1,2,3,4 | ||
| 324 | ``` | ||
| 325 | |||
| 326 | </YueDisplay> | ||
| 327 | |||
| 328 | ## 类声明语句 | ||
| 329 | |||
| 330 |   在类声明的主体中,除了键/值对外,我们还可以编写普通的表达式。在这种类声明体中的普通代码的上下文中,self 等于类对象,而不是实例对象。 | ||
| 331 | |||
| 332 |   以下是创建类变量的另一种方法: | ||
| 333 | |||
| 334 | ```yuescript | ||
| 335 | class Things | ||
| 336 | @class_var = "hello world" | ||
| 337 | ``` | ||
| 338 | <YueDisplay> | ||
| 339 | |||
| 340 | ```yue | ||
| 341 | class Things | ||
| 342 | @class_var = "hello world" | ||
| 343 | ``` | ||
| 344 | |||
| 345 | </YueDisplay> | ||
| 346 | |||
| 347 |   这些表达式会在所有属性被添加到类的基对象后执行。 | ||
| 348 | |||
| 349 |   在类的主体中声明的所有变量都会限制作用域只在类声明的范围。这对于放置只有类方法可以访问的私有值或辅助函数很方便: | ||
| 350 | |||
| 351 | ```yuescript | ||
| 352 | class MoreThings | ||
| 353 | secret = 123 | ||
| 354 | log = (msg) -> print "LOG:", msg | ||
| 355 | |||
| 356 | some_method: => | ||
| 357 | log "hello world: " .. secret | ||
| 358 | ``` | ||
| 359 | <YueDisplay> | ||
| 360 | |||
| 361 | ```yue | ||
| 362 | class MoreThings | ||
| 363 | secret = 123 | ||
| 364 | log = (msg) -> print "LOG:", msg | ||
| 365 | |||
| 366 | some_method: => | ||
| 367 | log "hello world: " .. secret | ||
| 368 | ``` | ||
| 369 | |||
| 370 | </YueDisplay> | ||
| 371 | |||
| 372 | ## @ 和 @@ 值 | ||
| 373 | |||
| 374 |   当 @ 和 @@ 前缀在一个名字前时,它们分别代表在 self 和 self.\_\_class 中访问的那个名字。 | ||
| 375 | |||
| 376 |   如果它们单独使用,它们是 self 和 self.\_\_class 的别名。 | ||
| 377 | |||
| 378 | ```yuescript | ||
| 379 | assert @ == self | ||
| 380 | assert @@ == self.__class | ||
| 381 | ``` | ||
| 382 | <YueDisplay> | ||
| 383 | |||
| 384 | ```yue | ||
| 385 | assert @ == self | ||
| 386 | assert @@ == self.__class | ||
| 387 | ``` | ||
| 388 | |||
| 389 | </YueDisplay> | ||
| 390 | |||
| 391 |   例如,使用 @@ 从实例方法快速创建同一类的新实例的方法: | ||
| 392 | |||
| 393 | ```yuescript | ||
| 394 | some_instance_method = (...) => @@ ... | ||
| 395 | ``` | ||
| 396 | <YueDisplay> | ||
| 397 | |||
| 398 | ```yue | ||
| 399 | some_instance_method = (...) => @@ ... | ||
| 400 | ``` | ||
| 401 | |||
| 402 | </YueDisplay> | ||
| 403 | |||
| 404 | ## 构造属性提升 | ||
| 405 | |||
| 406 |   为了减少编写简单值对象定义的代码。你可以这样简单写一个类: | ||
| 407 | |||
| 408 | ```yuescript | ||
| 409 | class Something | ||
| 410 | new: (@foo, @bar, @@biz, @@baz) => | ||
| 411 | |||
| 412 | -- 这是以下声明的简写形式 | ||
| 413 | |||
| 414 | class Something | ||
| 415 | new: (foo, bar, biz, baz) => | ||
| 416 | @foo = foo | ||
| 417 | @bar = bar | ||
| 418 | @@biz = biz | ||
| 419 | @@baz = baz | ||
| 420 | ``` | ||
| 421 | <YueDisplay> | ||
| 422 | |||
| 423 | ```yue | ||
| 424 | class Something | ||
| 425 | new: (@foo, @bar, @@biz, @@baz) => | ||
| 426 | |||
| 427 | -- 这是以下声明的简写形式 | ||
| 428 | |||
| 429 | class Something | ||
| 430 | new: (foo, bar, biz, baz) => | ||
| 431 | @foo = foo | ||
| 432 | @bar = bar | ||
| 433 | @@biz = biz | ||
| 434 | @@baz = baz | ||
| 435 | ``` | ||
| 436 | |||
| 437 | </YueDisplay> | ||
| 438 | |||
| 439 |   你也可以使用这种语法为一个函数初始化传入对象的字段。 | ||
| 440 | |||
| 441 | ```yuescript | ||
| 442 | new = (@fieldA, @fieldB) => @ | ||
| 443 | obj = new {}, 123, "abc" | ||
| 444 | print obj | ||
| 445 | ``` | ||
| 446 | <YueDisplay> | ||
| 447 | |||
| 448 | ```yue | ||
| 449 | new = (@fieldA, @fieldB) => @ | ||
| 450 | obj = new {}, 123, "abc" | ||
| 451 | print obj | ||
| 452 | ``` | ||
| 453 | |||
| 454 | </YueDisplay> | ||
| 455 | |||
| 456 | ## 类表达式 | ||
| 457 | |||
| 458 |   类声明的语法也可以作为一个表达式使用,可以赋值给一个变量或者被返回语句返回。 | ||
| 459 | |||
| 460 | ```yuescript | ||
| 461 | x = class Bucket | ||
| 462 | drops: 0 | ||
| 463 | add_drop: => @drops += 1 | ||
| 464 | ``` | ||
| 465 | <YueDisplay> | ||
| 466 | |||
| 467 | ```yue | ||
| 468 | x = class Bucket | ||
| 469 | drops: 0 | ||
| 470 | add_drop: => @drops += 1 | ||
| 471 | ``` | ||
| 472 | |||
| 473 | </YueDisplay> | ||
| 474 | |||
| 475 | ## 匿名类 | ||
| 476 | |||
| 477 |   声明类时可以省略名称。如果类的表达式不在赋值语句中,\_\_name 属性将为 nil。如果出现在赋值语句中,赋值操作左侧的名称将代替 nil。 | ||
| 478 | |||
| 479 | ```yuescript | ||
| 480 | BigBucket = class extends Bucket | ||
| 481 | add_drop: => @drops += 10 | ||
| 482 | |||
| 483 | assert Bucket.__name == "BigBucket" | ||
| 484 | ``` | ||
| 485 | <YueDisplay> | ||
| 486 | |||
| 487 | ```yue | ||
| 488 | BigBucket = class extends Bucket | ||
| 489 | add_drop: => @drops += 10 | ||
| 490 | |||
| 491 | assert Bucket.__name == "BigBucket" | ||
| 492 | ``` | ||
| 493 | |||
| 494 | </YueDisplay> | ||
| 495 | |||
| 496 |   你甚至可以省略掉主体,这意味着你可以这样写一个空白的匿名类: | ||
| 497 | |||
| 498 | ```yuescript | ||
| 499 | x = class | ||
| 500 | ``` | ||
| 501 | <YueDisplay> | ||
| 502 | |||
| 503 | ```yue | ||
| 504 | x = class | ||
| 505 | ``` | ||
| 506 | |||
| 507 | </YueDisplay> | ||
| 508 | |||
| 509 | ## 类混合 | ||
| 510 | |||
| 511 |   你可以通过使用 `using` 关键字来实现类混合。这意味着你可以从一个普通 Lua 表格或已定义的类对象中,复制函数到你创建的新类中。当你使用普通 Lua 表格进行类混合时,你有机会用自己的实现来重写类的索引方法(例如元方法 `__index`)。然而,当你从一个类对象做混合时,需要注意的是该类对象的元方法将不会被复制到新类。 | ||
| 512 | |||
| 513 | ```yuescript | ||
| 514 | MyIndex = __index: var: 1 | ||
| 515 | |||
| 516 | class X using MyIndex | ||
| 517 | func: => | ||
| 518 | print 123 | ||
| 519 | |||
| 520 | x = X! | ||
| 521 | print x.var | ||
| 522 | |||
| 523 | class Y using X | ||
| 524 | |||
| 525 | y = Y! | ||
| 526 | y\func! | ||
| 527 | |||
| 528 | assert y.__class.__parent ~= X -- X 不是 Y 的父类 | ||
| 529 | ``` | ||
| 530 | <YueDisplay> | ||
| 531 | |||
| 532 | ```yue | ||
| 533 | MyIndex = __index: var: 1 | ||
| 534 | |||
| 535 | class X using MyIndex | ||
| 536 | func: => | ||
| 537 | print 123 | ||
| 538 | |||
| 539 | x = X! | ||
| 540 | print x.var | ||
| 541 | |||
| 542 | class Y using X | ||
| 543 | |||
| 544 | y = Y! | ||
| 545 | y\func! | ||
| 546 | |||
| 547 | assert y.__class.__parent ~= X -- X 不是 Y 的父类 | ||
| 548 | ``` | ||
| 549 | |||
| 550 | </YueDisplay> | ||
