Solution

ID: past-exam-of-the-year-1-of-the-computer-science-course-of-the-university-of-oxford/2016/imperative-programming-resit/7/c/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.
Figure 1.
Decorator pattern for the cable television account, extended with Sports
. Details.
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. 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. [ref]

New to topics? Read the docs here!