Orientação a objetos e frameworks

Documentos relacionados
Luciano Ramalho setembro/2012. Objetos Pythonicos. Orientação a objetos e padrões de projeto em Python

Luciano Ramalho setembro/2012. Objetos Pythonicos. Orientação a objetos e padrões de projeto em Python

Computação II (MAB 225)

Luciano Ramalho setembro/2012. Objetos Pythonicos. Orientação a objetos e padrões de projeto em Python

Descritores de atributos em Python

Produtividade e qualidade em Python através da metaprogramação

Programação Orientada a Objetos em Python

Luciano Ramalho dezembro/2012. Objetos Pythonicos. Orientação a objetos e padrões de projeto em Python

Python para quem sabe Python

Python: Exceções, Iteradores e Geradores. Claudio Esperança

Os elementos da programação

Curso de Python em 5 Horas

Programação procedimental

Computadores e Programação Engª Biomédica Departamento de Física Faculdade de Ciências e Tecnologia da Universidade de Coimbra Ano Lectivo 2003/2004

Aula de hoje. Expressões. Expressões. Expressões. Exemplos. Programa em Python. SCC Introdução à Programação para Engenharias

Algoritmos e estrutura de dados

SCC0124 Introdução à Programação para Engenharias

Introdução a Programação Orientada a Objetos

Orientação a Objetos e Java

Computação II (MAB 225)

PROGRAMAÇÃO E PYTHON. Laboratórios de Informática João Paulo Barraca, André Zúquete, Diogo Gomes

Luciano Ramalho setembro/2012. Objetos Pythonicos. Orientação a objetos e padrões de projeto em Python

TCC 00308: Programação de Computadores I Organização de programas em Python

Aula passada. Aula passada... Sequências Funções puras e modificadores. Listas Tuplos

Computação II MAB 225. Brunno Goldstein.

Computação 1 - Python Aula 6 - Teórica: Listas 1/ 28

Conceitos de Programação Orientada por Objectos. Rui Camacho Programação 2

Programação Orientada a Objetos

Orientação a Objetos parte 2 ENCAPSULAMENTO, CLASSES, HERANÇAS

[Linguagem de Programação 3] [Aula 01] [Gustavo Yoshio Maruyama]

Programação Orientada a Objectos - P. Prata, P. Fazendeiro

Padrão para a codificação em Python

Gabriel Giorisatto De Angelo Luiz Otávio Gerhardt Fernandes

Nas aulas anteriores Strings. Ciclos

Organização de programas em Python. Vanessa Braganholo

Introdução a orientação a objetos

Funções. Prof. Alberto Costa Neto Programação em Python

Programação Orientada a Objectos - P. Prata, P. Fazendeiro

Programação I Aula 19 Aritmética com racionais Pedro Vasconcelos DCC/FCUP

Paradigmas de Linguagens de Programação. Suporte para Programação Orientada a Objeto

Python: Classes. Claudio Esperança

Laboratório de Programação 1 Aula 04

Introdução à Programação / Programação I

Dicionários. Operações Aliases, cópias. Os tipos de dados compostos que estudamos até ao momento (strings, listas, tuplos) são sequenciais:

Computação I - Python Aula 1 - Teórica: Manipulação de Strings, Tuplas e Listas

Aula de hoje. Tipos de Dados e Variáveis. Constantes literais. Dados. Variáveis. Tipagem dinâmica. SCC Introdução à Programação para Engenharias

Conceitos de Programação Orientada a Objetos

Fundamentos da Programação

Computadores e Programação Engª Biomédica Departamento de Física Faculdade de Ciências e Tecnologia da Universidade de Coimbra Ano Lectivo 2005/2006

Programação Orientada a Objetos. Vagner Luz do Carmo - Vluzrmos

Informática Aplicada à Engenharia Florestal

Python: Listas. Claudio Esperança

Computação II (MAB 225)

Nomes, Amarração, Verificação de Tipos, e Escopo

Linguagens de Programação

MC-102 Aula 02 Shell Interativa, Programa Básico, Variáveis, Atribuições, Tipos Simples. Instituto de Computação Unicamp

Algoritmos e Estrutura de Dados Aula 02 Listas em Python

Programação orientada a objetos

Programação com objectos

Linguagens de Programação

1 Expressões, valores e tipos 1. 2 Variáveis e atribuições 5. cálculo de expressões segue a estrutura de parênteses e as prioridades dos operadores

Computação 1 - Python Aula 3 - Teórica: Tipos de dados, Strings, Estrutura Condicional 1/ 28

Programação de Computadores

Algoritmos e Programação

Programação orientada a objetos: exemplo com frações (conclusão)

Lista de Linguagens de Programação 16

Computação 1 - Python Aula 10 - Teórica: Estrutura de Dados - Dicionário. João Carlos, Carla Delgado, Ana Luisa Duboc 1/ 18

COMPORTAMENTOS - Observações

Listas, conjuntos e dicionários

Conceitos de Linguagens de Programação - Características. Paavo Soeiro

Python: Dicionários. Claudio Esperança

Características de Python. Inteligência Artificial. Baixando e Instalando. Operadores. Variáveis. Strings 9/10/2010

Estruturas de Dados em Python

Luciano Iteráveis, geradores & cia: o caminho pythonico

Orientação a objetos. Programação. Orientada a Objetos. Orientação a objetos. Orientação a objetos. Abstração e encapsulamento

Computação 2. Aula 8 Teórica professor: Leonardo Carvalho

Sequências - Tuplas. Sequências - Tuplas

Computação 1 - Python Aula 4 - Teórica Variáveis e Atribuição, Strings. João Carlos, Carla Delgado, Ana Luisa Duboc 1/ 30

Requisitos de sistemas

Algoritmos e estrutura de dados

Orientação a Objetos com Ruby

Projeto de Linguagem. Linguagens de Programação

Universidade da Beira Interior Cursos: Engenharia Informática, Matemática /Informática e Ensino da Informática

Paradigmas de Programação. Java First-Tier: Aplicações. Orientação a Objetos em Java (I) Nomenclatura. Paradigma OO. Nomenclatura

Luciano Ramalho setembro/2012. Objetos Pythonicos. Orientação a objetos e padrões de projeto em Python

INF1636 PROGRAMAÇÃO ORIENTADA A OBJETOS

Nesta aula... Diagramas da stack. Recursão. 1 Funções. 2 Valores booleanos e condicionais. 3 Execução condicional e recursão

Computação I - Python Aula 4 - Teórica: Variáveis e Atribuição, Strings

Abaixo iremos pormenorizar cada um de seus atributos:

Reinaldo Gomes Análise/projeto estruturado

Programação Orientada a Objectos - P. Prata, P. Fazendeiro. JAVA6 e Programação Orientada Pelos Objectos, F. Mário Martins, FCA, Julho de 2009.

Paradigmas de Linguagens de Programação. Expressões e Instruções de Atribuição

Programação Orientada a Objetos

Programação I Aula 17 Correção de programas Pedro Vasconcelos DCC/FCUP

Linguagem de Programação e Compiladores

Polimorfismo. O que é polimorfismo?

C O N S T R U T O R E S E S O B R E C A R G A P R O F. M E. H É L I O E S P E R I D I Ã O

Linguagens de Programação 2015/1. Ruby. Diego Rodrigues Leonardo Rodrigues

Computação 2. Aula 7 Teórica professor: Leonardo Carvalho

Introdução à Ciência da Computação Disciplina:

Transcrição:

Orientação a objetos e frameworks 1

Objetivo deste módulo Apresentar conceitos fundamentais de: orientação a objetos organização de programas em vários módulos Explicar conceitos a partir do nível básico para: programadores que nunca usaram OO programadores que já usaram OO em outras linguagens 2

Orientação a objetos: a origem Linguagem Simula 1967 Noruega: Ole-Johan Dahl e Kristen Nygaard objetos, classes, sub-classes métodos virtuais (funções associadas a objetos específicos em tempo de execução) 3

Orientação a objetos: evolução Smalltalk 1980 EUA, Xerox PARC (Palo Alto Research Center): Alan Kay, Dan Ingalls, Adele Goldberg et. al. terminologia: Object oriented programming message passing, late binding (a idéia por trás de métodos virtuais) 4

Smalltalk 1980 5

Squeak: Smalltalk livre 6

Conceito: objeto Um componente de software que inclui dados (atributos) e comportamentos (métodos) Em geral, os atributos são manipulados pelos métodos do próprio objeto (encapsulamento) Figuras: bycicle (bicicleta), The Java Tutorial http://docs.oracle.com/javase/tutorial/java/concepts/object.html 7

Exemplo: um objeto dict >>> d = {'AM':'Manaus', 'PE':'Recife', 'PR': 'Curitiba'} >>> d.keys() ['PR', 'AM', 'PE'] >>> d.get('pe') 'Recife' >>> d.pop('pr') 'Curitiba' >>> d {'AM': 'Manaus', 'PE': 'Recife'} >>> len(d) 2 >>> d. len () 2 Métodos: keys, get, pop, len etc. 8

Exemplo: um objeto dict Sobrecarga de operadores: [ ]: getitem >>> d {'AM': 'Manaus', 'PE': 'Recife'} setitem >>> d['am'] 'Manaus' >>> d. getitem ('AM') 'Manaus' >>> d['mg'] = 'Belo Horizonte' >>> d. setitem ('RJ', 'Rio de Janeiro') >>> d {'MG': 'Belo Horizonte', 'AM': 'Manaus', 'RJ': 'Rio de Janeiro', 'PE': 'Recife'} 9

Exemplo: um objeto dict Atributos de dados: class, doc >>> d. class <type 'dict'> >>> print d. doc dict() -> new empty dictionary. dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs. dict(seq) -> new dictionary initialized as if via: d = {} for k, v in seq: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2) 10

Exemplo: um objeto dict Em Python, métodos também são atributos >>> dir(d) [' class ', ' cmp ', ' contains ', ' delattr ', ' delitem ', ' doc ', ' eq ', ' format ', ' ge ', ' getattribute ', ' getitem ', ' gt ', ' hash ', ' init ', ' iter ', ' le ', ' len ', ' lt ', ' ne ', ' new ', ' reduce ', ' reduce_ex ', ' repr ', ' setattr ', ' setitem ', ' sizeof ', ' str ', ' subclasshook ', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values'] 11

Exemplo: um objeto Tkinter.Label import Tkinter from time import strftime relogio = Tkinter.Label() relogio.pack() relogio['font'] = 'Helvetica 120 bold' relogio['text'] = strftime('%h:%m:%s') def tictac(): agora = strftime('%h:%m:%s') if agora!= relogio['text']: relogio['text'] = agora relogio.after(100, tictac) Note: Em Tkinter, atributos de dados são acessados via [ ]: getitem e setitem tictac() relogio.mainloop() 12

Objetos em linguagens Existem linguagens baseadas em objetos e linguagens orientadas a objetos baseadas em objetos: permitem que o programador use os tipos de objetos fornecidos, mas não permitem que ele crie seus próprios tipos de objetos Ex. Visual Basic antes da era.net 13

Objetos em Python Tudo é objeto: não existem tipos primitivos desde Python 2.2, dezembro de 2001 >>> 5 + 3 8 >>> 5. add (3) 8 >>> type(5) <type 'int'> 14

Funções são objetos >>> def fatorial(n):... '''devolve n!'''... return 1 if n < 2 else n * fatorial(n-1)... >>> fatorial(5) 120 >>> fat = fatorial >>> fat <function fatorial at 0x1004b5f50> >>> fat(42) 1405006117752879898543142606244511569936384000000000L >>> fatorial. doc 'devolve n!' >>> fatorial. name 'fatorial' >>> fatorial. code <code object fatorial at 0x1004b84e0, file "<stdin>", line 1> >>> fatorial. code.co_varnames ('n',) 15

Funções são objetos >>> fatorial. code.co_code ' \x00\x00d\x01\x00j\x00\x00o\x05\x00\x01d\x02\x00s\x01 \x00\x00t\x00\x00 \x00\x00d\x02\x00\x18\x83\x01\x00\x14s' >>> from dis import dis >>> dis(fatorial. code.co_code) 0 LOAD_FAST 0 (0) 3 LOAD_CONST 1 (1) 6 COMPARE_OP 0 (<) 9 JUMP_IF_FALSE 5 (to 17) Bytecode da 12 POP_TOP 13 LOAD_CONST 2 (2) 16 RETURN_VALUE função fatorial >> 17 POP_TOP 18 LOAD_FAST 0 (0) 21 LOAD_GLOBAL 0 (0) 24 LOAD_FAST 0 (0) 27 LOAD_CONST 2 (2) 30 BINARY_SUBTRACT 31 CALL_FUNCTION 1 34 BINARY_MULTIPLY 35 RETURN_VALUE >>> 16

Objetos têm tipo Tipagem forte: normalmente, Python não faz conversão automática entre tipos >>> a = 10 >>> b = '9' >>> a + b Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for +: 'int' and 'str' >>> a + int(b) 19 >>> str(a) + b '109' >>> 77 * None Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for *: 'int' and 'NoneType' >>> 17

Tipagem dinâmica: variáveis não têm tipo >>> def dobro(x):... return x * 2... >>> dobro(7) 14 >>> dobro(7.1) 14.2 >>> dobro('bom') 'bombom' >>> dobro([10, 20, 30]) [10, 20, 30, 10, 20, 30] >>> dobro(none) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in dobro TypeError: unsupported operand type(s) for *: 'NoneType' and 'int' 18

Duck typing Se voa como um pato, nada como um pato e grasna como um pato, é um pato. Tipagem dinâmica permite duck typing (tipagem pato) estilo de programação que evita verificar os tipos dos objetos, mas apenas seus métodos No exemplo anterior, a função dobro funciona com qualquer objeto x que consiga fazer x * 2 19

Tipagem forte x fraca Tipagem forte x fraca refere-se a conversão automática de valores de JavaScript (ECMAScript 5) em Node.js 0.6 tipos diferente. Linguagens de tipagem fraca são muito liberais na mistura entre tipos, e isso é uma fonte de bugs. Veja alguns resultados estranhos obtidos com JavaScript, que tem tipagem fraca. Em Python as três expressões acima geram TypeError, e as três últimas resultam False. Python tem tipagem forte. > 10 + '9' '109' > 10 + '9' * 1 19 > '10' + 9 * 1 '109' > 0 == '0' true > 0 == '' true > '0' == '' false 20

Tipagem forte x fraca, dinâmica x estática Tipagem forte x fraca refere-se a conversão automática de valores de tipos diferentes Tipagem dinâmica x estática refere-se à declaração dos tipos das variáveis, parâmetros formais e valores devolvidos pelas funções Linguagens de tipagem estática exigem a declaração dos tipos, ou usam inferência de tipos para garantir que uma variável será associada a somente a valores de um tipo 21

Tipagem em linguagens Smalltalk dinâmica forte Python dinâmica forte Ruby dinâmica forte C (K&R) estática fraca C (ANSI) estática forte Java estática forte C# estática forte JavaScript dinâmica fraca } combinação perigosa: PHP dinâmica fraca bugs sorrateiros 22

Conversões automáticas Python faz algumas (poucas) conversões automáticas entre tipos: Promoção de int para float Promoção de str para unicode assume o encoding padrão: ASCII por default >>> 6 * 7.0 42.0 >>> 'Spam, ' + u'eggs' u'spam, eggs' >>> 23

Funções para inspecionar objetos type(obj): devolve o tipo do objeto o tipo é uma classe dir(obj): devolve os nomes dos atributos do objeto métodos e atributos de dados devolve uma lista útil para uso interativo, mas não necessariamente completa 24

Objetos podem receber novos atributos Em geral, é possível atribuir valores a atributos não pré-definidos, em tempo de execução. Exceções: tipos embutidos, tipos com slots >>> fatorial <function fatorial at 0x1004b5f50> >>> fatorial._autor = 'Fulano de Tal' >>> fatorial._autor 'Fulano de Tal' >>> s = 'sapo' >>> s.nome = 'Joca' Traceback (most recent call last):... AttributeError: 'str' object has no attribute 'nome' 25

Acesso dinâmico a atributos getattr(obj, nome_do_atributo): acessar hasattr(obj, nome_do_atributo): testar setattr(obj, nome_do_atributo, valor): criar ou alterar delattr(obj, nome_do_atributo): remover 26

Acesso dinâmico >>> dobro <function dobro at 0x1004412a8> >>> dobro. doc 'devolve duas vezes x' >>> getattr(dobro, ' doc ') 'devolve duas vezes x' >>> hasattr(dobro, 'peso') False >>> setattr(dobro, '_inspecao', '2012-01-31') >>> dobro._inspecao '2012-01-31' >>> del dobro._inspecao >>> hasattr(dobro, '_inspecao') False 27

Acesso dinâmico >>> t = (1,) >>> type(t) <type 'tuple'> >>> for nome_atr in dir(t):... print nome_atr.ljust(16), getattr(t, nome_atr)... add <method-wrapper ' add ' of tuple object at... class <type 'tuple'> contains <method-wrapper ' contains ' of tuple object at... delattr <method-wrapper ' delattr ' of tuple object at... doc tuple() -> empty tuple tuple(iterable) -> tuple initialized from iterable's items subclasshook <built-in method subclasshook of type object at. If the argument is a tuple, the return value is the same object. eq <method-wrapper ' eq ' of tuple object at... format <built-in method format of tuple object at... [...] len <method-wrapper ' len ' of tuple object at... [...] str <method-wrapper ' str ' of tuple object at... count <built-in method count of tuple object at... index <built-in method index of tuple object at... 28

Conceito: classe Uma categoria, ou tipo, de objeto Uma idéia abstrata, uma forma platônica Exemplo: classe Cão : Eu digo: Ontem eu comprei um cão Você não sabe exatamente qual cão, mas sabe: é um mamífero, quadrúpede, carnívoro pode ser domesticado (normalmente) cabe em um automóvel 29

Exemplar de cão: instância da classe Cao >>> rex = Cao() instanciação 30

Classe Cao class Mamifero(object): """lição de casa: implementar""" instanciação class Cao(Mamifero): qt_patas = 4 carnivoro = True nervoso = False def init (self, nome): self.nome = nome def latir(self, vezes=1): # quando nervoso, late o dobro vezes = vezes + (self.nervoso * vezes) print self.nome + ':' + ' Au!' * vezes def str (self): return self.nome def repr (self): return 'Cao({0!r})'.format(self.nome) >>> rex = Cao('Rex') >>> rex Cao('Rex') >>> print rex Rex >>> rex.qt_patas 4 >>> rex.latir() Rex: Au! >>> rex.latir(2) Rex: Au! Au! >>> rex.nervoso = True >>> rex.latir(3) Rex: Au! Au! Au! Au! Au! Au! modulo2.git/cao.py 31

Classe Cao em Python class Mamifero(object): """lição de casa: implementar""" class Cao(Mamifero): qt_patas = 4 carnivoro = True nervoso = False def init (self, nome): self.nome = nome def latir(self, vezes=1): # quando nervoso, late o dobro vezes = vezes + (self.nervoso * vezes) print self.nome + ':' + ' Au!' * vezes def str (self): return self.nome def repr (self): return 'Cao({0!r})'.format(self.nome) atributos de dados na classe funcionam como valores default para os atributos das instâncas init é o construtor, ou melhor, o inicializador modulo2.git/cao.py 32

Classe Cao em Python class Mamifero(object): """lição de casa: implementar""" class Cao(Mamifero): qt_patas = 4 carnivoro = True nervoso = False def init (self, nome): self.nome = nome def latir(self, vezes=1): # quando nervoso, late o dobro vezes = vezes + (self.nervoso * vezes) print self.nome + ':' + ' Au!' * vezes def str (self): return self.nome def repr (self): return 'Cao({0!r})'.format(self.nome) self é o 1º parâmetro em todos os métodos de instância atributos da instância só podem ser acessados via self modulo2.git/cao.py 33

Classe Cao class Mamifero(object): """lição de casa: implementar""" class Cao(Mamifero): qt_patas = 4 carnivoro = True nervoso = False def init (self, nome): self.nome = nome def latir(self, vezes=1): # quando nervoso, late o dobro vezes = vezes + (self.nervoso * vezes) print self.nome + ':' + ' Au!' * vezes def str (self): return self.nome def repr (self): return 'Cao({0!r})'.format(self.nome) invocação >>> rex = Cao('Rex') >>> rex Cao('Rex') >>> print rex Rex >>> rex.qt_patas 4 >>> rex.latir() Rex: Au! >>> rex.latir(2) Rex: Au! Au! na invocação do método, a instância é passada implicitamente na posição do self modulo2.git/cao.py 34

Mamifero: superclasse de Cao class Mamifero(object): """lição de casa: implementar""" class Cao(Mamifero): qt_patas = 4 carnivoro = True nervoso = False def init (self, nome): self.nome = nome def latir(self, vezes=1): # quando nervoso, late o dobro vezes = vezes + (self.nervoso * vezes) print self.nome + ':' + ' Au!' * vezes def str (self): return self.nome def repr (self): return 'Cao({0!r})'.format(self.nome) UML diagrama de classe generalização modulo2.git/cao.py 35

Subclasses de Cao Continuação de cao.py class Pequines(Cao): nervoso = True class Mastiff(Cao): def latir(self, vezes=1): # o mastiff não muda seu latido quando nervoso print self.nome + ':' + ' Wuff!' * vezes class SaoBernardo(Cao): def init (self, nome): Cao. init (self, nome) self.doses = 10 def servir(self): if self.doses == 0: raise ValueError('Acabou o conhaque!') self.doses -= 1 msg = '{0} serve o conhaque (restam {1} doses)' print msg.format(self.nome, self.doses) Diz a lenda que o cão São Bernardo leva um pequeno barril de conhaque para resgatar viajantes perdidos na neve. 36

Subclasses de Cao class Pequines(Cao): nervoso = True class Mastiff(Cao): def latir(self, vezes=1): # o mastiff não muda seu latido quando nervoso print self.nome + ':' + ' Wuff!' * vezes class SaoBernardo(Cao): def init (self, nome): Cao. init (self, nome) self.doses = 10 def servir(self): if self.doses == 0: raise ValueError('Acabou o conhaque!') self.doses -= 1 msg = '{0} serve o conhaque (restam {1} doses)' print msg.format(self.nome, self.doses) >>> sansao = SaoBernardo('Sansao') >>> sansao.servir() Sansao serve o conhaque (restam 9 doses) >>> sansao.doses = 1 >>> sansao.servir() Sansao serve o conhaque (restam 0 doses) >>> sansao.servir() Traceback (most recent call last):... ValueError: Acabou o conhaque! 37

Subclasses de Cao Continuação de cao.py class Pequines(Cao): nervoso = True class Mastiff(Cao): def latir(self, vezes=1): # o mastiff não muda seu latido quando nervoso print self.nome + ':' + ' Wuff!' * vezes class SaoBernardo(Cao): def init (self, nome): Cao. init (self, nome) self.doses = 10 def servir(self): if self.doses == 0: raise ValueError('Acabou o conhaque!') self.doses -= 1 msg = '{0} serve o conhaque (restam {1} doses)' print msg.format(self.nome, self.doses) 38

Relógio com classe import Tkinter from time import strftime class Relogio(Tkinter.Label): def init (self): Tkinter.Label. init (self) self.pack() self['text'] = strftime('%h:%m:%s') self['font'] = 'Helvetica 120 bold' self.tictac() def tictac(self): agora = strftime('%h:%m:%s') if agora!= self['text']: self['text'] = agora self.after(100, self.tictac) rel = Relogio() rel.mainloop() modulo2.git/relogio_oo.py 39

Uma pequena parte da hierarquia de classes do Tkinter herança múltipla mixin herança múltipla 40

Um pouco mais da hierarquia de classes do Tkinter 41

Hierarquia de classes dos objetos gráficos dotkinter 42

Herança múltipla Refatoração de cao.py para cao2.py Reutilizar o latido do mastiff em outros cães grandes mixin herança múltipla herança múltipla class Cao(Mamifero): qt_patas = 4 carnivoro = True nervoso = False def init (self, nome): self.nome = nome def latir(self, vezes=1): # quando nervoso, late o dobro vezes = vezes + (self.nervoso * vezes) print self.nome + ':' + ' Au!' * vezes def str (self): return self.nome def repr (self): return 'Cao({0!r})'.format(self.nome) class Grande(object): """ Mixin: muda o latido""" def latir(self, vezes=1): # faz de conta que cães grandes não mudam # seu latido quando nervosos print self.nome + ':' + ' Wuff!' * vezes class Mastiff(Grande, Cao): """ O mastiff é o maior cão que existe """ class SaoBernardo(Grande, Cao): def init (self, nome): Cao. init (self, nome) self.doses = 10 def servir(self): if self.doses == 0: raise ValueError('Acabou o conhaque!') self.doses -= 1 msg = '{0} serve o conhaque (restam {1} doses)' print msg.format(self.nome, self.doses) modulo2.git/cao2.py 43

Herança múltipla class Cao(Mamifero): qt_patas = 4 carnivoro = True nervoso = False def init (self, nome): self.nome = nome def latir(self, vezes=1): # quando nervoso, late o dobro vezes = vezes + (self.nervoso * vezes) print self.nome + ':' + ' Au!' * vezes def str (self): return self.nome def repr (self): return 'Cao({0!r})'.format(self.nome) class Grande(object): """ Mixin: muda o latido""" def latir(self, vezes=1): # faz de conta que cães grandes não mudam # seu latido quando nervosos print self.nome + ':' + ' Wuff!' * vezes class Mastiff(Grande, Cao): """ O mastiff é o maior cão que existe """ class SaoBernardo(Grande, Cao): def init (self, nome): Cao. init (self, nome) self.doses = 10 def servir(self): if self.doses == 0: raise ValueError('Acabou o conhaque!') self.doses -= 1 msg = '{0} serve o conhaque (restam {1} doses)' print msg.format(self.nome, self.doses) modulo2.git/cao2.py 44

As duas hierarquias de um sistema OO Hierarquia de classes is-a: é um Hierarquia de objetos part-of: parte de Object-oriented Analysis and Design with Applications 2ed. - Grady Booch 45

As duas hierarquias de um sistema OO Object-oriented Analysis and Design with Applications 3ed. - Booch et. al. 46

from Tkinter import Frame, Label, Button Timer class Timer(Frame): def init (self): Frame. init (self) self.inicio = self.agora = 15 self.pendente = None # alarme pendente self.grid() self.mostrador = Label(self, width=2, anchor='e', font='helvetica 120 bold',) self.mostrador.grid(column=0, row=0, sticky='nswe') self.bt_start = Button(self, text='start', command=self.start) self.bt_start.grid(column=0, row=1, sticky='we') self.atualizar_mostrador() def atualizar_mostrador(self): self.mostrador['text'] = str(self.agora) def start(self): if self.pendente: self.after_cancel(self.pendente) self.agora = self.inicio self.atualizar_mostrador() self.pendente = self.after(1000, self.tictac) Exemplo simples de composição def tictac(self): self.agora -= 1 self.atualizar_mostrador() if self.agora > 0: self.pendente = self.after(1000, self.tictac) timer = Timer() timer.mainloop() modulo2.git/timer.py 47

from Tkinter import Frame, Label, Button Timer class Timer(Frame): def init (self): Frame. init (self) self.inicio = self.agora = 15 self.pendente = None # alarme pendente self.grid() self.mostrador = Label(self, width=2, anchor='e', font='helvetica 120 bold',) self.mostrador.grid(column=0, row=0, sticky='nswe') self.bt_start = Button(self, text='start', command=self.start) self.bt_start.grid(column=0, row=1, sticky='we') self.atualizar_mostrador() def atualizar_mostrador(self): self.mostrador['text'] = str(self.agora) def start(self): if self.pendente: self.after_cancel(self.pendente) self.agora = self.inicio self.atualizar_mostrador() self.pendente = self.after(1000, self.tictac) def tictac(self): self.agora -= 1 self.atualizar_mostrador() if self.agora > 0: self.pendente = self.after(1000, self.tictac) timer = Timer() timer.mainloop() modulo2.git/timer.py 48

Composição Arranjo de partes de um sistema mostrador = Label() componentes, sub-componentes... bt_start = Button() timer = Timer() 49

instanciação instanciação from Tkinter import Frame, Label, Button class Timer(Frame): def init (self): Frame. init (self) self.inicio = self.agora = 15 self.pendente = None # alarme pendente self.grid() self.mostrador = Label(self, width=2, anchor='e', font='helvetica 120 bold',) self.mostrador.grid(column=0, row=0, sticky='nswe') self.bt_start = Button(self, text='start', command=self.start) self.bt_start.grid(column=0, row=1, sticky='we') self.atualizar_mostrador() def atualizar_mostrador(self): self.mostrador['text'] = str(self.agora) def start(self): if self.pendente: self.after_cancel(self.pendente) self.agora = self.inicio self.atualizar_mostrador() self.pendente = self.after(1000, self.tictac) def tictac(self): self.agora -= 1 self.atualizar_mostrador() if self.agora > 0: self.pendente = self.after(1000, self.tictac) instanciação timer = Timer() timer.mainloop() modulo2.git/timer.py 50

Composição em UML composição composição 51