Universidade do Estado do Rio de Janeiro
Instituto de Química
Prof André Luís Alberton
Índice

Classes¶

Vamos a algumas definições que permitem o entendimento de classes e objetos:

  • objetos - são variáveis que contém variáveis internas e métodos
  • classes - são construtores de objetos

É como se a classe representasse o conceito e o objeto propriamente dito a concretização da classe.

Considere por exemplo a classe Cachorro, representando um conceito abstrato; e objetos como Rex e Toto, representando a concretização do conceito.

É uma convenção que as classes sejam nomeadas com a primeira letra maiúscula (ex Cachorro). Se o nome for combinado, as primeiras letras de cada palavra seriam maiúsculas, embora a palavra deva ser escritas juntas (CachorroGrande).

Os métodos devem conter o self se forem se referir à subvariáveis ou métodos da própria classe.

Vejamos um exemplo.

In [16]:
class Cachorro:
    # definimos 'subvariáveis'
    raca = None # texto descritivo
    peso = None # em kg
    rabo = None # texto descritivo
    cor = None # texto descritivo
    temperamento = None # texto descritivo
    latido = None # texto a conter 'alto' ou 'baixo'
    
    # definimos um método
    def latir(self):
        if self.latido == 'alto':
            print('AU-AU-AU')
        if self.latido=='estridente':
            print('rrr-aaau-rrrr-aaau-aaau')
        elif self.latido == 'baixo':
            print('au-au-au')
🐕

Acima criamos uma classe. Agora, vamos concretizar o objeto Rex.

In [18]:
# Criando o Rex
Rex = Cachorro
Rex.raca = 'Pitbull'
Rex.peso = 30
Rex.rabo = 'curto'
Rex.cor = 'preto'
Rex.temperamento = 'manso'
Rex.latido = 'alto'
Rex.latir(Rex) # poderíamos usar Cachorro.latir(Rex)
AU-AU-AU

⚠ Alerta: chance de perda de dados por sobre-escrita

Objetos podem 'ser sobre-escritos'; na verdade, podendo ser nomes de variáveis possuem o mesmo espaço na memória do computador. Considere o exemplo abaixo.

In [20]:
# Criando o Rex
Rex = Cachorro
Rex.raca = 'Pitbull'
Rex.peso = 30
Rex.rabo = 'curto'
Rex.cor = 'preto'
Rex.temperamento = 'manso'
Rex.latido = 'alto'
Rex.latir(Rex) # poderíamos usar Rex.latir(Rex)
AU-AU-AU
In [21]:
# Criando o Toto
Toto = Cachorro
Toto.raca = 'Pinscher'
Toto.peso = 4
Toto.rabo = 'curto'
Toto.cor = 'preto'
Toto.temperamento = 'demonstra raiva'
Toto.latido = 'estridente'
Toto.latir(Toto) # poderíamos usar Toto.latir(Toto)
rrr-aaau-rrrr-aaau-aaau
In [22]:
# Revendo as propriedades do Rex
print(Rex.raca)
Pinscher

Ué, mas o Rex não era um Pitbull?

Na verdade, na forma escrita, Rex e Toto referenciam-se ao mesmo objeto. Havíamos escrito que Rex era um Pitbull, mas Toto passou a ser ma variável que referencia-se ao mesmo objeto; ao mudar Toto, mudamos Rex. Podemos verificar isto com o comando is. O comando O is compara a identidade do objeto, isto é, o valor de referência de seu endereço na memória (Alura).

In [6]:
Rex is Toto
Out[6]:
True

É mais ou menos como a figura do Homem Aranha abaixo.

Homemaranha


Para evitar a 'sobreposição de dados' e criar objetos particularizados, podemos usar o comando __init__ com atribuição de dados específicos ao criarmos objetos gerados a partir de classes; com a obrigatoriedade de informar pelo menos um valor particularizado para o objeto. O self refere-se ao próprio objeto e deve estar sempre presente. Vejamos um exemplo.

In [1]:
class Cachorro2:
    
    def __init__(self,raca,peso,rabo,cor,temperamento,latido):
        # definimos 'subvariáveis'
        self.raca = raca # texto descritivo
        self.peso = peso # em kg
        self.rabo = rabo # texto descritivo
        self.cor = cor # texto descritivo
        self.temperamento = temperamento # texto descritivo
        self.latido = latido # texto a conter 'alto' ou 'baixo'
        # definimos um método
    def latir(self):
        if self.latido == 'alto':
            print('AU-AU-AU')
        if self.latido=='estridente':
            print('rrr-aaau-rrrr-aaau-aaau')
        elif self.latido == 'baixo':
            print('au-au-au')
        return(None)


# Criando a Mel (nome da cachorra)
Mel = Cachorro2('Shihtzu',5,'longo','branca e cinza','mansa','baixo')
Cachorro2.latir(Mel)

# Criando a Safira (nome da cachorra)
Safira = Cachorro2('Safira',20,'longo','marrom','brava','alto')
Cachorro2.latir(Safira)

# imprimindo a raça da Mel
print(Mel.raca)
au-au-au
AU-AU-AU
Shihtzu

Agora sim, os objetos ficaram particularizados!!

Teste

Para que os objetos fiquem particularizados, pelo menos uma informação deve ser dada. Por exemplo, a raca abaixo escrita pode ser informada para ser atribuída, e os demais podem permanecer sem informação. Se não for informada nenhuma variável específica, os objetos podem ser sobrepostos.

In [1]:
class Cachorro3:
    
    def __init__(self,raca):
        # definimos 'subvariáveis'
        self.raca =raca # texto descritivo
        self.peso = None # em kg
        self.rabo = None # texto descritivo
        self.cor = None # texto descritivo
        self.temperamento = None # texto descritivo
        self.latido = None # texto a conter 'alto' ou 'baixo'
        # definimos um método
    def latir(self):
        if self.latido == 'alto':
            print('AU-AU-AU')
        if self.latido=='estridente':
            print('rrr-aaau-rrrr-aaau-aaau')
        elif self.latido == 'baixo':
            print('au-au-au')
        return(None)

# Cria o cachorro SAS com um viralatas (Srd atualmente)
Sas = Cachorro3('Srd')
Sas.peso = 17 # Define o peso do cachorro Sas
Sas.latido='alto' # Define o tipo de latido do cachorro Sas
# Cria o cachorro duque
Duque = Cachorro3('Pequenes')
Duque.peso = 5 # Define o peso do cachorro Duque
Duque.latido='baixo' # Define o tipo de latido do cachorro Duque

Note que, no código acima, informamos a raca pelo método __init__. O peso foi informado posteriormente. Contudo, o peso do cachorro Sas foi preservado, conforme pode ser visto abaixo.

In [2]:
print(Sas.peso)
17

Observe que o objeto Sas é diferente do objeto Duque, conforme segue.

In [3]:
Sas is Duque
Out[3]:
False

Os métodos podem então ser acionados conforme abaixo.

In [4]:
# Latido da SAS
Sas.latir() # acionando por Sas
Cachorro3.latir(Sas) # acionando por Cachorro3
# Latido do Duque
Duque.latir() # acionando por Duque
Cachorro3.latir(Duque) # acionando por Cachorro3
AU-AU-AU
AU-AU-AU
au-au-au
au-au-au

Subclasses¶

A partir de uma classe 'Pai', podemos criar uma classe 'Filho', que herda todas as propriedades da classe 'Pai'. Por exemplo.

In [7]:
# Classe 'Pai'
class Reator:
    tipo = None
    volume = None
    cor_ent = None
    cor_sai = None
    reacoes = None
    caracteristica = None

# Classe 'Filho'
class ReatorPFR(Reator):
    # Define um método para a classe filho
    def __init__(self,nome):
        self.nome=nome
        self.tipo = "PFR"
        self.fluxo = "empistonado"

# Classe 'Filho'
class ReatorCSTR(Reator):
    # Define um método para a classe filho
    def __init__(self,nome):
        self.nome=nome
        self.tipo = "CSTR"
        self.fluxo = "mistura perfeita"

# Define os reatores Reat1 e Reat2
Reat1 = ReatorPFR('Reator 1')
Reat2 = ReatorCSTR('Reator 2')

# Imprime propriedades dos reatores
print([Reat1.nome,Reat1.tipo,Reat1.fluxo])
print([Reat2.nome,Reat2.tipo,Reat2.fluxo])
['Reator 1', 'PFR', 'empistonado']
['Reator 2', 'CSTR', 'mistura perfeita']

Se as classes Pai e Filho tiverem ambas os métodos __init__, os objetos criados a partir da classe Filho terão como __init__ (apenas) apenas o que foi definido na classe Filho. Contudo, a classe filho consegue acessar o init da classe Pai com o comando __super__. Vejamos um exemplo.

In [9]:
# Classe 'Pai', equipamento
class Equipamento:
    Volume = None
    def __init__(self,TAG):
        self.TAG = TAG
    
# Classe 'Filho'
class Coluna(Equipamento):
    # Define um método para a classe filho
    def __init__(self,TAG,Diametro,Altura):
        super().__init__(TAG) # aciona a função de inicilização da classe Pai
        self.D = Diametro # define o diâmetro
        self.H = Altura # define a altura

# Cria o objeto Col1, chamado C1, com diâmetro 2 e altura 7
Col1 = Coluna('C1',2,7)

# Imprime propriedades das colunas
print([Col1.TAG,Col1.D,Col1.H])
['C1', 2, 7]

Há muito mais o que ser falado sobre classes. Contudo, será desenvolvido ao longo do material.