Solution (source code)

= Solution

In this <UML class diagram>, hollow triangles point toward the more general type; dashed lines denote realization of the `CableTV` <object interface>. The plain association records that `Packages` retains one wrapped account, without claiming exclusive lifetime ownership.

\Image[/past-exam-of-the-year-1-of-the-computer-science-course-of-the-university-of-oxford/2016/imperative-resit-decorator-uml.png]
{title=<Decorator pattern> for the cable television account, extended with Sports}

Add the following <software class> and client application to the supplied declarations. The inherited result type gives `BasicPlan.cost` an expected `Double` type, so its literal `30` is widened appropriately; no source change is needed.
``
class Sports(account: CableTV) extends Packages(account) {
  override def cost: Double = super.cost + 5.0
  override def packages: String = super.packages + ", Sports"
}

object CheckCableTV {
  def show(account: CableTV): Unit =
    println(account.packages + ": GBP " + account.cost)

  def main(args: Array[String]): Unit = {
    val basic: CableTV = new BasicPlan
    val movies: CableTV = new Movies(basic)
    val hd: CableTV = new HDChannels(movies)
    val sports: CableTV = new Sports(hd)
    show(basic)
    show(movies)
    show(hd)
    show(sports)
    assert(sports.cost == 52.0)
    assert(sports.packages == "Basic plan, Movies, HD channels, Sports")
  }
}
``
The printed accounts have costs `30.0`, `40.0`, `47.0`, and `52.0`, with each description extending the preceding one. \b[The fully decorated account is `Basic plan, Movies, HD channels, Sports`, costing £52.] The intermediate accounts remain available because wrapping constructs a new <software object>. <Scala 2.11.12 method type inference implementation>[methodSig and typesFromOverridden: inherited return type supplies the expected type while typing an overriding body]{ref}