Generalização e Especialização
Projeto de Sistemas
Generalização e Especialização
É possível definirmos tipos genéricos que agreguem
um conjunto de definições comuns a um grande
número de objetos (Generalização). A partir destas
especificações genéricas podemos construir novos
tipos, mais específicos, que acrescentem novas
características e comportamentos aos já existentes
(Especialização).
• Relação semântica “is a” (“é um” / “é uma”) :
um mamífero é um animal• Relação de inclusão nas extensões dos tipos:
Universo de Design supertipo
subtipo x x x
x x objeto
extensão (subtipo)
ↄ
extensão (supertipo) SupertipoSubtipo
generalização especialização
Animal Mamífero
• Relação de herança nas propriedades:
O subtipo herda as propriedades (atributos, operações e relações) do supertipo, podendo acrescentar outrasHerança em linguagens OO
• Herança é a capacidade de uma classe definir o seu
comportamento e sua estrutura aproveitando definições de
outra classe, normalmente conhecida como superclasse,
classe base ou classe mãe.
Classe Mãe
Observando essa figura podemos notar que a classe filha herda tudo o que a classe mãe possui e acrescenta alguma coisa.
Propriedades das classes
Exemplo: Diferença entre tipos de
conta bancária
Uma conta corrente tem um saldo extra (chamado
especial) além do seu saldo em conta;
Uma conta poupança, diferentemente, não permite realizar
uma retirada além do seu saldo;
Uma vez por mês, o saldo de uma conta poupança é
reajustado de acordo com a taxa da poupança no mês;
Classes diferentes para tipos diferentes
Todas essas diferenças evitam definir uma única
classe para contas de um banco;
Ou seja, podemos definir uma classe ContaCorrente
e outra ContaPoupanca;
ContaCorrente - numero : integer - dv : integer - saldo : real - limite : real + checarDV(numero : integer, dv: ContaPoupanca - numero : integer - dv : integer - saldo : real - taxaJuros : real + checarDV(numero : integer, dv:Características em comum
Com as duas classes não temos o inconveniente, por
exemplo, de ter uma conta poupança com saldo
especial;
Entretanto, temos valores de número e dígito
verificador (dv), únicos, declarados em dois locais
E temos de replicar também o código de checagem de
dígito verificador nas duas classes
Uma solução para este problema é colocarmos as
características comuns num local comum entre as
classes
Classe com características comuns
Conta
- numero : integer - dv : integer
- saldo : real
+ checarDV(numero : integer, dv : integer) : boolean + retornarSaldo() : real
Representando herança em UML
Shape Spline Ellipse Polygon Shape Spline Ellipse PolygonShared Target Style Separate Target Style
. . .
. . .
Mais um exemplo no PDV
Credit Authorization Service Check Authorization Service Check Payment AuthorizationService address name phoneNumber additional associations superclass justified bycommon attributes and associations Store Authorizes-payments-of
*
Authorizes Credit Payment Authorizes*
*
*
1 1Person
attributes operations
Nem tudo é generalizável
(viola a heurística “é-um” ou “é-um-tipo-de”)
Arm attributes operations Leg attributes operations Head attributes operations
Generalização em vários níveis
Hiearquia:
Transacao Solicitacao Resposta Resposta Cartao Resposta Cheque Solicitacao Cartao Solicitacao ChequeSupertipos e Subtipos
Supertipo
Tipo cujas características e comportamentos são
herdados por outros tipos.
Subtipo
Tipo que herda definições de um outro tipo. Em
geral acrescenta novas características e /ou
Conformidade da definição de
subtipos
Todos os subtipos de
Pagamento devem ter uma
quantia e pagar uma
Venda.
Regra dos 100%
O subtipo deve se conformar a 100% dos atributos e
Conformidade do conjunto de
subtipos
• PagamentoCartao deve ser um membro do conjunto de
Pagamentos
O que é um subtipo correto?
• Um subtipo potencial deve atender às duas
regras de conformidade anteriores:
– Regra dos 100% (conformidade da definição)
– Regra é-um (conformidade da pertinência)
Quando definir um subtipo?
• O subtipo tem atributos adicionais de interesse, ou
• O subtipo tem associações adicionais de interesse, ou
• O conceito subtipo é operado, tratado, reagido a, ou
manipulado de maneira diferente do supertipo ou dos outros
subtipos de maneiras que são de interesse considerar, ou
Quando definir um supertipo?
• Os subtipos potenciais representam variações de um
conceito similar
• Os subtipos potenciais aderem às regras dos 100% e
é-um
• Todos os subtipos têm atributos comuns que podem ser
fatorados e expressos no supertipo
• Todos os subtipos têm associações comuns que podem
ser fatoradas e relacionadas com o supertipo
Polimorfismo
• É a possibilidade de se solicitar um serviço a um
objeto, cuja execução vai depender do tipo de objeto
instanciado.
• Com o conceito de amarração tardia (late binding), o
tipo do objeto não é descoberto em tempo de
compilação; em conseqüência, o mesmo vale para o
método a ser chamado
Polimorfismo
Suponha que existam três classes disponíveis numa
biblioteca: Triângulo, Retângulo e Quadrado. Todas
elas possuem um serviço ou método chamado
desenhar() com os mesmos parâmetros de
entrada e saída.
desenhar() Classe Triângulo Classe Retângulo Classe RetânguloExemplo de polimorfismo
class Nota {
private int value;
private Nota(int val) { value = val; } public static final Nota
DO_MEDIO = new Nota(0),
DO_SUSTENIDO = new Nota(1), SI_BEMOL = new Nota(2); } // Etc.
class Instrumento {
public void toque(Nota n) {
Exemplo de polimorfismo (cont.)
// Instrumentos de sopro também são instrumentos // porque eles tem a mesma interface:
class Sopro extends Instrumento { // Redefina o método da interface: public void toque(Nota n) {
System.out.println("Sopro.toque()"); }
}
// Instrumentos de cordas também são instrumentos // porque eles tm a mesma interface:
class Corda extends Instrumento { // Redefina o método da interface: public void toque(Nota n) {
System.out.println("Corda.toque()"); }
Exemplo de polimorfismo (cont.)
public class Musica {
public static void afine(Instrumento i) { // ...
i.toque(Nota.DO_MEDIO); }
public static void main(String[] args) { Sopro flauta = new Sopro();
afine(flauta); // Upcasting
Instrumento violino = new Corda(); afine(violino); // Upcasting
Classes abstratas em UML
• Classe abstrata: classe que
não pode ter instâncias
diretas
– pode ter instâncias indiretas
pelas subclasses concretas
• Operação abstrata: operação
com implementação a ser
definida nas subclasses
– uma classe com operações
abstratas tem de ser abstrata
• Notação : nome em
Icon RectangularIcon ArbitraryIcon origin: Point display() getID(): Integer height: Integer width: Integer edge:LineCollection display() isInside(p:Point):BoolExemplo de classe abstrata
<<abstract>> Role attributes operations Faculty attributes operations Student attributes operations Staff attributes operations Visitor attributes operationsClasses abstratas em Java
• Classes abstratas são classes que não produzem instâncias.
• Agrupam características e comportamentos que serão
herdados por outras classes.
• Fornecem padrões de comportamento que serão
implementados nas suas subclasses.
abstract class Figura {
protected int x; // centro da fig. x protected int y; // centro da fig. y public figura (int x1, int y1){
x = x1; y = y1;
public void move (int x1, int y1){ this.apaga();
x = x1; y = y1;
Exemplo de classes abstratas
Exemplo
class Quadrado extends Figura { int l; // lado do quadrado
public Quadrado(int x1, int y1, int l1) { super(x1, y1);
l = l1; }
public void desenha( ) {
System.out.println("Desenhando quadrado (" + x + "," + y + ") lado "+ l ); }
public void apaga( ) {
System.out.println("Apagando quadrado (" + x + "," + y + ") lado " + l ); }
Exemplo de classes abstratas (cont.)
....
Figura q = new Quadrado(20,30,10);
q.desenha();
q.move(50,40);
q.apaga();
...
Classes abstratas e polimorfimo
• Geralmente, classes abstratas e polimorfismo
caminham juntos
• Utiliza-se a classe abstrata para:
– implementar métodos concretos
– especificar métodos abstratos
• A classe filha da classe abstrata implementa
herança polimórfica
Exemplo de classes abstratas e
polimorfismo
abstract class Instrumento { int i;
public abstract void toque(); public String qual() {
return "Instrumento"; }
public abstract void afine(); }
class Sopro extends Instrumento { public void toque() {
System.out.println("Sopro.toque()"); }
Exemplo de classes abstratas e
polimorfismo (cont.)
class Percussao extends Instrumento { public void toque() {
System.out.println("Percussao.toque()"); }
public String qual() { return "Percussao"; } public void afine() {}
}
class Corda extends Instrumento { public void toque() {
System.out.println("Corda.toque()"); }
public String qual() { return "Corda"; } public void afine() {}
Exemplo de classes abstratas e
polimorfismo (cont.)
class Metal extends Sopro { public void toque() {
System.out.println("Metal.toque()"); }
public void afine() {
System.out.println("Metal.afine()"); }
}
class Madeira extends Sopro { public void toque() {
System.out.println("Madeira.toque()"); }
Exemplo de classes abstratas e
polimorfismo (cont.)
public class MusicaConcreta {
// Não se importa com o tipo, assim novos instrumentos
// adicionados ao sistema funcionarao corretamente:
static void afine(Instrumento i) { // ...
i.toque(); }
static void afineTodos(Instrumento[] e) { for(int i = 0; i < e.length; i++)
afine(e[i]); }
public static void main(String[] args) { Instrumento[] orchestra = new
Instrumento[5]; int i = 0;
// Upcasting durante adicao a array: orchestra[i++] = new Sopro();
orchestra[i++] = new Percussao(); orchestra[i++] = new Corda(); orchestra[i++] = new Metal(); orchestra[i++] = new Madeira(); afineTodos(orchestra);
} }