Ir para o conteúdo

Exemplos

Um outro exemplo de Classe: conta no banco

  • Atributos: nome, número da conta, saldo;
  • Métodos: depósito, saque, saída formatada.
class ContaBanco:
    def __init__(self, nome, numero_conta, deposito_inicial):
        self.nome = nome
        self.no = numero_conta
        self.saldo = deposito_inicial

    def deposito(self, movimentacao):
        self.saldo += movimentacao

    def saque(self, movimentacao):
        self.saldo -= movimentacao

    def info(self):
        s = '%s, %s, saldo: %s' % \
            (self.nome, self.no, self.saldo)
        print s

Exemplo de uso:

>>> a1 = ContaBanco('Joaquim Porto', '19371554951', 20000)
>>> a2 = ContaBanco('Manuel Carvalho',  '19371564761', 20000)
>>> a1.deposito(1000)
>>> a1.saque(4000)
>>> a2.saque(10500)
>>> a1.saque(3500)
>>> print "a1's saldo:", a1.saldo
a1's saldo: 13500
>>> a1.info()
Joaquim Porto, 19371554951, saldo: 13500
>>> a2.info()
Manuel Carvalho, 19371564761, saldo: 9500

Use o caractere _ para evitar o mau uso

Possível, mas não intencionado ao uso:

>>> a1.nome = 'Qualquer Outro Nome'
>>> a1.saldo = 100000
>>> a1.no = '19371564768'

As afirmações para o uso correto:

  • Os atributos não devem ser modificados!
  • O atributo saldo pode ser visualizado.
  • Modificação do saldo é feita através de saque ou deposito.

Remédio:

Atributos ou métodos não intencionados ao uso fora da classe podem ser marcados como protegidos através do prefixo _ antes de seu nome (ex.: _nome). Isso é apenas uma convenção, não existe forma técnica de evitar que atributos e métodos seja acessados.

class ContaBancoM:
    def __init__(self, nome, numero_conta, deposito_inicial):
        self._nome = nome
        self._no = numero_conta
        self._saldo = deposito_inicial

    def deposito(self, movimentacao):
        self._saldo += movimentacao

    def saque(self, movimentacao):
        self._saldo -= movimentacao

    def ver_saldo(self):    ## NOVO - ver o valor do saldo
        return self._saldo

    def info(self):
        s = '%s, %s, saldo: %s' % \
            (self._nome, self._no, self._saldo)
        print s

Uso:

a1 = ContaBancoM('Maria Albertina', '19371554951', 20000)
a1.saque(4000)

print a1._saldo     ## funciona, mas quebra a convenção!

print a1.ver_saldo() ## forma correta de ver o saldo

a1._no = '19371554955' ## isso é "crime"!

Um outro exemplo: contatos

  • Contatos contém uma lista de dados de pessoas;
  • Dados de uma pessoa: nome, celular, telefone comercial, telefone residencial, email;
  • Vamos criar uma classe para os dados sobre uma pessoa:
  • Métodos:
    • Construtor para inicializar nome e outros dados;
    • Adicionar novo número de celular;
    • Adicionar novo número comercial;
    • Adicionar novo número residencial;
    • Adicionar novo email;
    • Escrever uma saída sobre os dados pessoais.

Código básico:

class Pessoa:
    def __init__(self, nome,
                 num_celular=None, num_comercial=None,
                 num_residencial=None, email=None):
        self.nome = nome
        self.celular = num_celular
        self.comercial = num_comercial
        self.residencial = num_residencial
        self.email = email

    def ad_num_celular(self, numero):
        self.celular = numero

    def ad_num_comercial(self, numero):
        self.comercial = numero

    def ad_num_residencial(self, numero):
        self.residencial = numero

    def ad_email(self, endereco):
        self.email = endereco

Adicionando ao código um método de saída para mostrar os dados de uma pessoa:

class Pessoa:
    ...
    def saida(self):
        s = self.nome + '\n'
        if self.celular is not None:
            s += 'Telefone celular:   %s\n' % self.celular
        if self.comercial is not None:
            s += 'Telefone Comercial:   %s\n' % self.comercial
        if self.residencial is not None:
            s += 'Telefone Redidencial:  %s\n' % self.residencial
        if self.email is not None:
            s += 'Endereço de e-mail:  %s\n' % self.email
        print s

Uso:

p1 = Pessoa('Hans Petter Langtangen', email='hpl@simula.no')
p1.ad_num_comercial('67828283'),
p2 = Pessoa('Marco André Argenta', num_comercial='33616447')
p2.ad_email('marco.argenta@ufpr.br')
contatos = [p1, p2]                           ## lista
contatos = {'Langtangen': p1, 'Argenta': p2}   ## bem melhor!
for p in contatos:
    contatos[p].saida()

Mais um exemplo: uma classe para um círculo

  • Um círculo é definido pelo seu ponto central $x_0$, $y_0$ e seu raio $R$;
  • Esses dados podem ser atributos em uma classe;
  • Possíveis métodos na classe: area, circunferencia;
  • O construtor inicializa $x_0$, $y_0$ e $R$.
class Circulo:
    def __init__(self, x0, y0, R):
        self.x0, self.y0, self.R = x0, y0, R

    def area(self):
        return pi*self.R**2

    def circunferencia(self):
        return 2*pi*self.R

Uso:

>>> c = Circulo(2, -1, 5)
>>> print 'Um círculo com raio %g e centro em (%g, %g) tem área %g' % \
...       (c.R, c.x0, c.y0, c.area())
Um círculo com raio 5 e centro em (2, -1) tem área 78.5398

Para melhorar o código, podemos adicionar uma função teste para a classe circulo:

def test_Circulo():
    R = 2.5
    c = Circulo(7.4, -8.1, R)

    area_esperada = math.pi*R**2
    area_calculada = c.area()
    dif = abs(area_esperada - area_calculada)
    tol = 1E-14
    assert dif < tol, 'Problema no método Circulo.area, dif=%s' % dif

    circunferencia_esperada = 2*math.pi*R
    circunferencia_calculada = c.circunferencia()
    dif = abs(circunferencia_esperada - circunferencia_calculada)
    assert dif < tol, 'Problema no método Circulo.circunferencia, dif=%s' % dif

Aviso

Não esqueça do import math no início do código!