layout | title | partof | num | next-page | previous-page | language |
---|---|---|---|---|---|---|
tour |
Classes Genéricas |
scala-tour |
17 |
variances |
extractor-objects |
pt-br |
Semelhante ao Java 5 (aka. JDK 1.5), Scala tem suporte nativo para classes parametrizadas com tipos. Essas classes genéricas são particularmente úteis para o desenvolvimento de classes que representam coleções de dados. Aqui temos um exemplo que demonstra isso:
class Stack[T] {
var elems: List[T] = Nil
def push(x: T): Unit =
elems = x :: elems
def top: T = elems.head
def pop(): Unit = { elems = elems.tail }
}
A classe Stack
modela uma pilha mutável que contém elementos de um tipo arbitrário T
. Os parâmetros de tipo garantem que somente os elementos legais (que são do tipo T
) são inseridos na pilha. Da mesma forma, com os parâmetros de tipo podemos expressar que o método top
retorna somente elementos de um único tipo de dado, no caso, T
.
Aqui temos mais alguns exemplos de uso:
object GenericsTest extends App {
val stack = new Stack[Int]
stack.push(1)
stack.push('a')
println(stack.top)
stack.pop()
println(stack.top)
}
A saída do programa é:
97
1
Nota: subtipos de tipos genéricos são invariantes. Isto significa que se tivermos uma pilha de caracteres do tipo Stack[Char]
então ela não pode ser usada como uma pilha de inteiros do tipo Stack[Int]
. Isso seria incorreto porque isso nos permitiria inserir inteiros verdadeiros na pilha de caracteres. Para concluir, Stack[T]
é um subtipo de de Stack[S]
se e somente se S = T
. Como isso pode ser bastante restritivo, Scala oferece um mecanismo de anotação de parâmetro de tipo para controlar o comportamento de subtipo de tipos genéricos.