Companion object 2026-10-31
In Scala, a singleton object associated with a same-named companion class in the required source context. Object members and instance members are distinct: B.g(x) invokes a member of object B, while b.g(x) invokes an instance member through b. Both can use method overloading, but the instance's members are not automatically part of the companion's overload set.[ref]
Write each Scala trait linearization from most specific to least specific. Merge the parents' Scala trait linearizations right-to-left, removing a duplicate from the earlier portion when it also appears in the later portion. This retains every base once while respecting its required position after derived traits.[ref]
CityMan, City, Earth, Man, Mammal, Animal, Describe

BirdMan, City, Earth, Man, Mammal, Bird, Animal, Describe

BatMan, Man, Gotham, City, US, Earth, Bat, Mammal, Bird, Animal, Describe
For example, combining the final City with Gotham does not put City before its derived trait Gotham; duplicate removal places it after Gotham. Similarly Mammal and Bird remain after Bat, despite their occurrence through other parents.
Each describe calls super.describe before appending its own label. Thus execution enters implementations along the displayed Scala trait linearization, and appends labels in reverse order when calls return. The three printed lines are
Describe, Animal, Mammal, Man, Earth, City, 
Describe, Animal, Bird, Mammal, Man, Earth, City, 
Describe, Animal, Bird, Mammal, Bat, Earth, US, City, Gotham, Man, 
Each line has a final comma and space, because every printed string fragment includes them. The essential result is
List each Scala trait linearization from the most specific software class toward the common base, omitting predefined types:
Life1, Party, Study, Life
Life2, Sport, Exercise, Research, Party, Study, Life
Life3, Research, Study, Sport, Party, Exercise, Life
For example, Sport alone linearizes as Sport, Party, Exercise, Life, while Research alone gives Research, Party, Study, Life. In combining parents, take the right parent's linearization first, deleting from it entries also present in the remaining left-parent linearization, then append the latter. This places a common base after all of its derived traits.[ref]
An unqualified super.describe() continues after the current trait in the actual receiver's Scala trait linearization. Each override prints after its super call, so the output follows the displayed order backwards, starting at Life. The complete output is:
I live.
More on study.
More on party.
I live.
More on study.
More on party.
More on research.
More on exercise.
More on sport.
I live.
More on exercise.
More on party.
More on sport.
More on study.
More on research.
The first three lines belong to l1, the next six to l2, and the final six to l3.
Maintain one frequency count for each lowercase alphabet character. Update only after a successful delegated operation:
trait CharTrackPlugIn extends Doc {
  private val counts = Array.fill[Int](26)(0)

  private def lower(x: Char): Boolean = 'a' <= x && x <= 'z'

  abstract override def insert(x: Char, pos: Int): Unit = {
    super.insert(x, pos)
    if (lower(x)) counts(x - 'a') += 1
  }

  abstract override def delete(pos: Int): Char = {
    val old = super.delete(pos)
    if (lower(old)) counts(old - 'a') -= 1
    old
  }

  def getCount(x: Char): Int = {
    assert('a' <= x && x <= 'z')
    counts(x - 'a')
  }
}
For an initially empty underlying implementation that inserts the character it receives and returns the character actually deleted, the representation invariant is
Insertion increases exactly one applicable frequency count, and deletion decreases the count of the returned character. Uppercase and nonletter characters contribute nothing. Exceptions from failed underlying operations leave the counters unchanged. The stackable trait modification uses abstract override because it delegates to a concrete implementation elsewhere in the mixin chain.[ref]
The counters depend on the character seen by this trait. A later trait that transforms characters can break the stated underlying-operation assumption; part (d) deliberately exposes that order dependence.
Read each Scala trait linearization from the most specific implementation toward the base. For a declaration with parents , concatenate their linearizations from right to left, deleting a duplicate from a left operand when it already occurs in the right operand. This can move a repeated ancestor later than a superficial “rightmost trait first” scan suggests. Omitting the common AnyRef, Any suffix, the answers are
C, Y, H, N, L, I, E
B, Y, H, N, L, D, I, E
A, N, O, Y, S, H, T, L, D, I, E
For example, T contributes T,L,D,I,E, while O contributes O,Y,S,H,E. In A, the separately mentioned Y also appears in the later merge with O, and N's ancestors also occur in T; resolving these duplicates yields the final order displayed above. The inherited trait orders are the displayed lists after removing their leading class names. [ref]
The output becomes BCA, without a newline. Here each method body consists only of super.m; the semicolon ends that definition. The following print("B") or print("C") is a separate statement in the trait body, so it executes during construction.
Creating new D initializes the shared base and then the B and C mixins, printing BC. The subsequent d.m still forwards along C,B,A, but only A.m now prints anything, appending A. Thus it is the placement of the construction-time statements, not a changed Scala trait linearization, that changes the output. [ref]