Prof. Natalia Castro Fernandes Mestrado em Telecomunicações – UFF 2º semestre/2012 Introdução Forma de programar Programação não estruturada Programas simples e pequenos Ex: Cartões Programação Estruturada (ou Modular) Programas divididos em módulos Módulos com estruturas de dados internas Introdução Programação Orientada à Objetos Programas estruturados pelos dados e não pelas operações Dados, chamados de classe, especificam as operações válidas Módulos agrupados por dados e suas representações Unifica as ideias de algoritmos e estruturas de dados através do conceito de Objeto Programas organizados pelo comportamento dos objetos e não como uma simples sequência de comando e chamadas desconectadas. Classe É a representação de um tipo abstrato de dados Especifica: Atributos Métodos (funções) Define as propriedades e o comportamento dos conjuntos de objetos. Objeto É uma instância de uma classe Identificado univocamente pelo seu nome Possui estado, determinado pelo valor dos atributos ao longo do tempo Estado modificado pela aplicação dos métodos Mudança de estados define comportamento do objeto Conceitos de Orientação a Objetos Abstração Encapsulamento Hierarquia de classes e herança Polimorfismo Construtores e destrutores Abstração Objeto pode ser utilizado conhecendo-se apenas a sua interface Detalhes de implementação são ignorados Encapsulamento de dados e algoritmos Definidos dentro do objeto, não havendo necessidade de serem expostos na interface do objeto Encapsulamento Forma de definição dos objetos Classificação de atributos e métodos de acordo com o controle de acesso Classe composta de várias seções Privada – Podem ser acessados apenas pelos métodos do objeto Pública – Podem ser acessados por outros objetos Protegida – Podem ser acessados por métodos definidos na classe ou nas classes derivadas Em Python, tudo é público, mas existem meios para usar o privado. Veja mais em: http://docs.python.org/tutorial/classes.html Hierarquia de Classes e herança Pode-se desenvolver uma hierarquia de classe Criação de uma classe-raiz e diversas subclasses ou classes derivadas As classes-raiz representam as tarefas mais generalizadas As subclasses representam tarefas mais específicas Herdam as características das classes ascendentes Vantagem: Reaproveitamento de código! Herança Herança simples Uma classe tem apenas um pai Enlace Herança múltipla Uma classe tem vários pais Sem fio Ethernet Óptico Polimorfismo Uma mesma função pode ser definida de forma diferente por uma família de classes Comportamento definido pela definição do método em cada classe Exemplos Listas, tuplas e strings podem ser indexadas por um número entre colchetes e suportam o método len Se usarmos len(x), podemos passar uma lista, uma tupla ou uma string sem modificações ou indicações no código Redefinição de métodos de uma classe pai A classe enlace pode ter um método trata_erro genérico Esse método pode ser tratado de forma mais especifica dentro das classes filhas, que redefinem a função Construtores e destrutores São métodos especiais das classes O construtor é ativado quando se instancia o objeto de uma classe Faz as atribuições iniciais da classe Tem o nome da classe O destrutor da classe é ativado quando termina o escopo de um objeto Faz as ações finais antes de o objeto ser eliminado Quando não são declarados, o construtor apenas cria a área de memória necessária ao objeto e o destrutor a libera Orientação a objetos em Python Classe “Fábrica” de objetos A rigor, em Python, uma classe também é um objeto Uso de módulo.método é uma forma de usar um módulo como um objeto. O mesmo se aplica às classes Definição de uma classe class nome: var = valor ... var = valor def metodo (self, ... arg): ... def metodo (self, ... arg): ... Definição de classes Na definição dos métodos, os atributos são chamados como nome_da_classe.atributo O primeiro argumento de qualquer método é sempre self O self é uma referência a própria instância da classe É uma forma de a classe dizer que se refere a si mesma Atributos da classe podem ser chamados também como self.atributo Um objeto de uma classe é criado usando nome_da_classe() Exemplos – Criação de classes Exemplos – Criação de classes Exemplos (o que não fazer) Exemplos – Uso do self Exemplos – Atributos internos e externos Exemplos - Reescrevendo Atenção: o.extra() daria erro. Por que? Exercício Imagine que você está programando um site que deve vender pizza. A loja, o vendedor, o cliente, a pizza e o cardápio precisam ser representados. Crie as classes, com seus métodos (apenas imprimem o que deveriam fazer, mas recebem os argumentos corretos) e atributos. Construtores em Python Chamados automaticamente na criação de instâncias Utilizados declarando-se um método __init__ Exemplo Exemplo Destrutores A linguagem Python já apresenta um ‘coletor de lixo’ Gerenciamento de memória alocada feita de forma automática Uso dos destrutores para: Fechar sockets Fechar conexões com banco de dados Fechar arquivos Etc; Formato: __del__ Destrutores são chamados após o fim do escopo no qual o objeto está inserido Atenção: As mensagens do destrutor podem não aparecer no console que você está usando. (mensagens impressas apenas no sys.stderr ) Se houver necessidade de criar logs, usar arquivos e colocar exit no final do código. Exercício Crie uma classe para lidar com strings que tenha um construtor e um destrutor. A classe pode ter tantos argumentos você achar necessário, mas deve ter pelo menos um método. Encapsulamento Atributos públicos Todos os atributos de uma classe, por padrão Atributos privados Representados com __ na frente do nome Exemplos Exemplos Exercício Dois objetos de classes distintas, A e B, interagem da seguinte forma. Enquanto A não recebe um número primo do usuário, ele fica recebendo novos números. Quando recebe um número primo, ele ativa um atributo privado de B, de tal forma que B passa a pedir números para o usuário até receber um número não primo. Quando número é recebido, B seta um atributo privado de A, de tal forma que A volta para a operação inicial. Atenção: Utilize threads para representar o funcionamento das duas classes. Herança e Polimorfismo Para uma classe herdar atributos e métodos de outra, basta declarar isso na definição da classe Formato: Class Filha(Classe_Pai): Filha é uma sub-classe ou uma derivada de Classe_Pai e Classe_Pai é uma superclasse ou base de C É possível adicionar novos métodos e atributos à classe Filha, assim como é possível modificar métodos da Classe_Pai. Herança e Polimorfismo Caso um método ou um atributo seja redefinido e seja necessário chamar esse método ou atributo da superclasse, colocar essa chamada de forma explicita Construtores e destrutores da classe e da superclasse precisam ser chamados pelo construtor da nova classe Declaração de herança Declaração de novos atributos Redefinição de método Atributo definido na classe pai Uso da função pela definição do pai e do filho Redefinição de atributo Uso de atributo do pai e do filho Descomentando a linha pai.__init__(self) Construtores e herança O construtor da classe pai apenas atua sobre os atributos da classe filha Os atributos do pai chamados como pai.atributo não serão impactados pelo construtor do pai Cuidado ao sobrescrever indevidamente atributos Classes sem herança Classes que não herdam de outra classe do usuário podem ser definidas da seguinte forma: class sem_pai(object): Isso permite algumas propriedades especiais para a classe que não serão discutidas agora Mais informações em: http://docs.python.org/release/2.2.3/whatsnew/sectrellinks.html Herança de múltiplas classes Uma classe pode ter vários pais Herda os atributos e métodos de todas as classes pais Se duas classes pais possuírem o mesmo método ou o mesmo atributo, vale o atributo da classe declarada primeiro Exercício Crie um conjunto de classes, utilizando o conceito de herança, para representar as pessoas que interagem entre si em uma empresa. Módulo operador Permite reescrever o uso de comparações de objetos, operações lógicas e matemáticas, operações de sequência e testes de tipo abstrato Com isso, é possível reescrever o que deve ser feito quando se deseja somar ou subtrair dois objetos, por exemplo Módulo operador Principais funções operator.lt(a, b) ou operator.__lt__(a, b) operator.le(a, b) ou operator.__le__(a, b) operator.eq(a, b) ou operator.__eq__(a, b) operator.ne(a, b) ou operator.__ne__(a, b) operator.ge(a, b) ou operator.__ge__(a, b) operator.gt(a, b) ou operator.__gt__(a, b) Módulo operador Principais funções operator.is_(a, b) = Return a is b operator.abs(obj) operator.__abs__(obj) operator.add(a, b) operator.__add__(a, b) operator.and_(a, b) operator.__and__(a, b) operator.div(a, b) operator.__div__(a, b) operator.mod(a, b) operator.__mod__(a, b) Módulo operador Principais funções operator.neg(obj) operator.__neg__(obj) operator.or_(a, b) operator.__or__(a, b) operator.pos(obj) operator.__pos__(obj) operator.pow(a, b) operator.__pow__(a, b) operator.concat(a, b) operator.__concat__(a, b) operator.contains(a, b) operator.__contains__(a, b) Módulo operador operator.iadd(a, b) operator.__iadd__(a, b)a = iadd(a, b) a += b. operator.iand(a, b) operator.__iand__(a, b) a &= b. operator.iconcat(a, b) operator.__iconcat__(a, b) a += b for a and b sequences. operator.idiv(a, b) operator.__idiv__(a, b) a /= b Módulo operador operator.imod(a, b) operator.__imod__(a, b) a%= b. operator.imul(a, b) operator.__imul__(a, b) a *= b. operator.ior(a, b) operator.__ior__(a, b) a |= b. operator.ipow(a, b) operator.__ipow__(a, b) a **= b. Módulo operador Mais informações em: http://docs.python.org/library/operator.html Exercício Crie uma classe matriz que, com seu construtor, cria uma matriz m x n. Essa classe deve sobrescrever os métodos para adição, subtração, multiplicação e divisão, de tal forma que as operações sejam realizadas nas matrizes de forma adequada. Outras redefinições... __len__ Retorna o comprimento da sequencia Chamada: len(objeto) __del__ Chamada por del objeto[key] Apenas para (algumas) sequencias mutáveis Exercícios Modifique a classe de matrizes criada no exercício anterior, adicionando um novo método. Esse novo método verifica se dentro da matriz atual existem todas as vogais. Adicione mais um método que verifica se a soma de todos os inteiros presentes na matriz é um número regular. Um número é dito regular se sua decomposição em fatores primos apresenta apenas potências de 2, 3 e 5. Faça uma função que verifique se um número é ou não regular. Exercícios Desenvolva, com orientação a objetos, um programa que implemente o “jogo da velha” usando uma matriz de inteiros (use o 0 para o O e o 1 para o X). O programa deve permitir o jogo entre dois jogadores. A cada jogada o programa deve exibir a configuração atual do jogo ( matriz). Faça um algoritmo da solução, que deve ser executado no fim de cada jogada. Faça também o método que recebe a posição da jogada e diz qual o jogador atual. Crie uma classe para lidar com números. Essa classe, entre os seus métodos, deve apresentar: Um método que diz se um número é um capicua. Um número é capicua quando ele não muda se lido da esquerda para a direita ou da direita para a esquerda. Se o número for capicua, o método deve modificar o seu valor, somando 1. Um método que converta um número da base 10 para qualquer base entre 2 e 9, inclusive. Exercícios Crie uma classe para lidar com grafos. Um grafo G = (V;A) consiste em: um conjunto finito de vértices, V. um conjunto finito de arestas ligando dois vértices, A. A sua classe deve ter: um método para representar o grafo como uma lista de adjacências; um outro método para representar o grafo como uma matriz de adjacências; um método para determinar se dois vértices são vizinhos; Um método para determinar a lista de todos os vértices que são vizinhos de um dado vértice Um método para dizer a menor distância entre dois vértices quaisquer do grafo. Considere que cada vértice é representado por um número inteiro. Escreva um aplicativo para testar a classe.