abstract class Buffer {
  type T
  val element: T
}

abstract class SeqBuffer extends Buffer {
  type U
  type T <: Seq[U]
  def length = element.length
}

// IntSeqBuffer is abstract because element is abstract
abstract class IntSeqBuffer extends SeqBuffer {
  type U = Int
}

// implement IntSeqBuffer using a List as the sequence
class IntListBuffer extends IntSeqBuffer {
  type T = List[U] // or List[Int], U being an alias to Int
  val element = List(1, 2, 3)
}

// because of compound types, it's not unusual to use "anonymous" classes
// to implement abstract classes at instantiation time
new IntSeqBuffer {
  type T = List[U] // or List[Int], U being an alias to Int
  val element = List(1, 2, 3)
}

// Buffer is abstract because element is abstract
abstract class Buffer[T] {
  val element: T
}

// implementing the abstract class at instantiation time
new Buffer[Int] {
  val element = 42
}

abstract class SeqBuffer[U, T <: Seq[U]] extends Buffer[T] {
  def length = element.length
}

class IntListBuffer extends SeqBuffer[Int, List[Int]] {
  val element = List(1, 2, 3)
}
