Skip to content

Commit 498ce3b

Browse files
committed
Tutorials - Translation PT-BR - Abstract Types
1 parent 107761c commit 498ce3b

File tree

2 files changed

+80
-1
lines changed

2 files changed

+80
-1
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
---
2+
layout: tutorial
3+
title: Tipos Abstratos
4+
5+
disqus: true
6+
7+
tutorial: scala-tour
8+
num: 22
9+
tutorial-next: compound-types
10+
tutorial-previous: inner-classes
11+
language: pt-br
12+
---
13+
14+
Em Scala, as classes são parametrizadas com valores (parâmetros de construtor) e com tipos (se [classes genéricas](generic-classes.html)). Por razões de regularidade, só não é possível ter valores como membros de um objeto; tipos juntamente com valores são membros de objetos. Além disso, ambas as formas de membros podem ser concretas e abstratas.
15+
16+
Aqui está um exemplo que define uma definição de valor diferido e uma definição de tipo abstrato como membros de uma [trait](traits.html) chamada `Buffer`.
17+
18+
```tut
19+
trait Buffer {
20+
type T
21+
val element: T
22+
}
23+
```
24+
25+
*Tipos Abstratos* são tipos cuja identidade não é precisamente conhecida. No exemplo acima, só sabemos que cada objeto da classe `Buffer` tem um membro de tipo `T`, mas a definição de classe `Buffer` não revela para qual tipo concreto o membro do tipo `T` corresponde. Como definições de valores, podemos sobrescrever definições de tipos em subclasses. Isso nos permite revelar mais informações sobre um tipo abstrato ao limitar o tipo associado (o qual descreve as possíveis instâncias concretas do tipo abstrato).
26+
27+
No seguinte programa temos uma classe `SeqBuffer` que nos permite armazenar apenas as sequências no buffer ao definir que o tipo `-T` precisa ser um subtipo de `Seq[U]` para um novo tipo abstrato `U`:
28+
29+
```tut
30+
abstract class SeqBuffer extends Buffer {
31+
type U
32+
type T <: Seq[U]
33+
def length = element.length
34+
}
35+
```
36+
37+
[Traits](traits.html) ou [classes](classes.html) com membros de tipo abstratos são frequentemente utilizadas em combinação com instâncias de classe anônimas. Para ilustrar isso, agora analisamos um programa que lida com um buffer de sequência que se refere a uma lista de inteiros:
38+
39+
```tut
40+
abstract class IntSeqBuffer extends SeqBuffer {
41+
type U = Int
42+
}
43+
44+
object AbstractTypeTest1 extends App {
45+
def newIntSeqBuf(elem1: Int, elem2: Int): IntSeqBuffer =
46+
new IntSeqBuffer {
47+
type T = List[U]
48+
val element = List(elem1, elem2)
49+
}
50+
val buf = newIntSeqBuf(7, 8)
51+
println("length = " + buf.length)
52+
println("content = " + buf.element)
53+
}
54+
```
55+
56+
O tipo de retorno do método `newIntSeqBuf` refere-se a uma especialização da trait `Buffer` no qual o tipo `U` é agora equivalente a `Int`. Declaramos um tipo alias semelhante ao que temos na instanciação da classe anônima dentro do corpo do método `newIntSeqBuf`. Criamos uma nova instância de `IntSeqBuffer` na qual o tipo `T` refere-se a `List [Int]`.
57+
58+
Observe que muitas vezes é possível transformar os membros de tipo abstrato em parâmetros de tipo de classes e vice-versa. Aqui está uma versão do código acima que usa apenas parâmetros de tipo:
59+
60+
```tut
61+
abstract class Buffer[+T] {
62+
val element: T
63+
}
64+
abstract class SeqBuffer[U, +T <: Seq[U]] extends Buffer[T] {
65+
def length = element.length
66+
}
67+
object AbstractTypeTest2 extends App {
68+
def newIntSeqBuf(e1: Int, e2: Int): SeqBuffer[Int, Seq[Int]] =
69+
new SeqBuffer[Int, List[Int]] {
70+
val element = List(e1, e2)
71+
}
72+
val buf = newIntSeqBuf(7, 8)
73+
println("length = " + buf.length)
74+
println("content = " + buf.element)
75+
}
76+
```
77+
78+
Note que temos que usar [anotação de variância](variances.html) aqui; Caso contrário, não seríamos capazes de ocultar o tipo implementado pela sequência concreta do objeto retornado por `newIntSeqBuf`. Além disso, há casos em que não é possível substituir tipos abstratos com parâmetros de tipo.
79+

pt-br/tutorials/tour/variances.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,6 @@ object VariancesTest extends App {
3636
}
3737
```
3838

39-
A anotação `+T` declara o tipo `T` para ser usado somente em posições covariantes. Da mesma forma, `-T` declararia que `T` pode ser usado somente em posições contravariantes. Para os parâmetros de tipo covariante obtemos uma relação de sub-tipo covariante em relação ao parâmetro de tipo. Em nosso exemplo, isso significa que `Stack [T]` é um subtipo de `Stack [S]` se `T` for um subtipo de `S`. O oposto é válido para parâmetros de tipo que são marcados com um `-`.
39+
A anotação `+T` declara o tipo `T` para ser usado somente em posições covariantes. Da mesma forma, `-T` declara que `T` pode ser usado somente em posições contravariantes. Para os parâmetros de tipo covariante obtemos uma relação de sub-tipo covariante em relação ao parâmetro de tipo. Em nosso exemplo, isso significa que `Stack [T]` é um subtipo de `Stack [S]` se `T` for um subtipo de `S`. O oposto é válido para parâmetros de tipo que são marcados com um `-`.
4040

4141
No exemplo da pilha teríamos que usar o parâmetro de tipo covariante `T` em uma posição contravariante para podermos definir o método `push`. Uma vez que queremos sub-tipagem covariante para pilhas, usamos um truque e abstraímos o tipo de parâmetro do método `push`. Então temos um método polimórfico no qual usamos o tipo de elemento `T` como um limite inferior da variável de tipo da função `push`. Isso faz com que a variância de `T` fique em acordo com sua declaração, como um parâmetro de tipo covariante. Agora as pilhas são covariantes, mas a nossa solução permite que, por exemplo, seja possível inserir uma string em uma pilha de inteiros. O resultado será uma pilha do tipo `Stack [Any]`; Assim detectamos o error somente se o resultado for usado em um contexto onde esperamos uma pilha de números inteiros. Caso contrário, nós apenas criamos uma pilha com um tipo de elemento mais abrangente.

0 commit comments

Comments
 (0)