DI
UFPE
Sistema de Tipos de Eiffel
A Proposal for Making Eiffel Type-safe
W. R. Cook
ECOOP’87 Proceedings
Cambridge University Press, 1989
DI
UFPE
Sistema de Tipos de Eiffel
Sistema de tipos fortes
Relação de subtipo ligado a hierarquia de herança
Tipo
Tipo simples: REAL, INTEGER
Tipo classe: P[U1, ..., Un]
Parâmetro formal dentro de uma classe genérica
Tipo associação: like anchor
DI
UFPE
Sistema de Tipos de Eiffelclass Base feature base(n: Integer): Integer is do Result := n * 2 end;end
class Extra inherit Base feature extra(n: Integer): Integer is do Result := n * n end;end
DI
UFPE
Sistema de Tipos de Eiffel Conformidade de tipos: relação de subtipo
Y está em conformidade com X X e Y são idênticos X e Y são classes
X não é genérica, e Y é subclasse direta de X X é da forma P[U1, ..., Un] e Y é subclasse de
P[V1, ..., Vn] , onde Vi está em conformidade com Ui
Y é da forma like anchor, e o tipo de anchor está em conformidade com X
Há um tipo Z tal que Y está em conformidade com Z e Z está em conformidade com X
DI
UFPE
Sistema de Tipos de Eiffel Em resumo
Y está em conformidade com X se Y herda de X Logo, o mecanismo de herança
Deve garantir que objetos de uma subclasse podem ser usados quando objetos da superclasse forem esperados
Modificações que podem ser feitas em uma subclasse Adição de atributos Modificação da implementação dos métodos Modificação de tipos de atributos e métodos
DI
UFPE
Sistema de Tipos de Eiffel
Regra de redefinição de tipo
Um atributo, um resultado de função ou o argumento
de um método pode ser redeclarado com um novo
tipo em uma subclasse, desde que o novo tipo
esteja em conformidade com o tipo original.
DI
UFPE
Redefinição de Tipos de Atributosclass P1 feature class C1 inherit P1 a: Base; redefine a feature setup is a: Extra; local problem: Integer is x: Base; do do setup; x.Create; Result := a.extra(2); a := x; end; end; endend
Solução: uso de tipo associação
DI
UFPE
Redefinição de Tipos de Argumentosclass P2 feature get(arg: Base): Integer is do Result := arg.base(1) end;end
class C2 inherit P2 redefine get feature get(arg: Extra): Integer is do Result := arg.extra(2) end;end
DI
UFPE
Redefinição de Tipos de Argumentos Problema: C2 está em conformidade com P2
local a: Base; v: P2; b: C2do a.Create; b.Create; v := b; v.get(a);end
DI
UFPE
Redefinição de Tipo de Argumento Solução
O resultado e o argumento de um método pode ser redeclarado, desde que
Resultado: esteja em conformidade com o original
Argumento: o original esteja em conformidade com o novo tipo
Problema Redefinição de tipos se torna praticamente inútil
DI
UFPE
Métodos Declarados por Associação
Outro problema associado a nova regra de redefinição
Impacto no uso de tipos associação na declaração de
argumentos
Proibir o uso de tipos associação na definição de
argumentos?
Solução
Quando a âncora de um tipo de um argumento é
redeclarada, conformidade não é mantida
Mas outros problemas surgem
DI
UFPE
Mais um Problemaclass P3 feature base ... get(arg: like Current): Integer is
do Result := arg.base(1) end; not_assoc(arg: P3): Integer is
local x: P3; dox.Create;Result := arg.get(x);
end; subvert(arg: like Current): Integer is do
Result := not_assoc(arg); end;
end
DI
UFPE
Mais um Problemaclass C3 inherit P3 redefine get feature extra ...
get(arg: like Current): Integer is do Result := arg.extra(2) end;
end
c: C3c.subvert(c)
DI
UFPE
Conformidade de Tipos Genéricos Regras atuais
Não consideram que P[V] está em conformidade com P[U] quando V está em conformidade com U
Novas regras Y está em conformidade com X
X e Y são classes Y é subclasse direta de X X é da forma P[U1, ..., Un] e Y é da forma
P[V1, ..., Vn] , onde Vi está em conformidade com Ui
DI
UFPE
Conformidade de Tipos Genéricosclass Cell[T] feature info: T; change_info(x : T) is do info := x end;endlocal x: Base; a: Cell[Base]; b: Cell[Extra];do x.Create; b.Create; a:= b; a.change_info(x); b.info.extra(4);end
DI
UFPE
Conformidade de Tipos Genéricos Solução: identificar contextos de usos de parâmetros
Parâmetro covariante
Tipos de atributos e saídas de métodos
Parâmetro contravariante
Tipos de argumentos de métodos
Parâmetro bivariante
Tipos de atributos, saídas e argumentos de
métodos
DI
UFPE
Conformidade de Tipos Genéricos Nova regra
X e Y são classes, X é da forma P[U1, ..., Un] e Y é da forma P[V1, ..., Vn] , onde para cada para parâmetro Ti
se Ti é covariante
Vi está em conformidade com Ui
se Ti é contravariante
Ui está em conformidade com Vi
se Ti é bivariante
Vi é igual a Ui
DI
UFPE
Tipo Associação
Regra de conformidade forte demais
Y é da forma like anchor, e o tipo de anchor está em
conformidade com X
Se X é da forma like left-anchor, então Y tem que ser igual
DI
UFPE
Tipo Associação Porque...
class C feature left-anchor: U; x: like left-anchor; y: T; ... x := y; Se T estiver em
conformidade com U?end
DI
UFPE
Tipo Associaçãoclass D inherit C left-anchor: U’; ... x := y Pode ser inválido se T não estiver em conformidade com U’end
DI
UFPE
Tipo Associação Mas ...
class C feature left-anchor: U; x: like left-anchor; ... x := left-anchor; Deveria ser válidoend
DI
UFPE
Tipo Associação Além disso...
class C featurea: T;m(arg: like a) ...
end localc: C; b: T;
doc.m(b); Inválido
Solução: atributos de tipo
DI
UFPE
Mecanismo de Exportação Independência entre exportação e herança é falsa
locale: Extra; Hidden feature basev: Base;
dov := e;Result := v.base;
end Solução: desistir
DI
UFPE
Conclusão Recomendações
Substitua tipo associação com atributos de tipo
Elimine redefinição de tipo de atributo
Inverta regra de redefinição de argumento de método
Desconecte a relação de conformidade da relação de
herança
Considere as cláusulas ‘export’ cumulativas
Subclasses não são necessariamente subtipos
DI
UFPE
Resposta de Meyer “Catcalls” polimórficas são proibidas
“Catcall”: método que tem redefinição que pode causar problemas devido a sua remoção da lista de exportação ou novo tipo de argumento
Chamada polimórfica: o tipo do objeto alvo pode variar
Está a esquerda de atribuições É um argumento de método