Orientação a objeto no python e IDL

Em ciência da computação, o paradigma “orientação a objeto” tem bases conceituais e origem no campo de estudo da cognição (ato ou processo da aquisição do conhecimento que se dá através da percepção, raciocínio, memória, linguagem, etc), que influenciou a área de inteligência artificial e da linguística, no campo da abstração de conceitos do mundo real. Na programação orientada a objetos, implementa-se um conjunto de classes que definem os objetos presentes no sistema de software.

Resumo conceitual de orientação a objeto. Texto adaptado de Blog Etílico
Resumo conceitual de orientação a objeto. Texto adaptado de Blog Etílico.

Um objeto é uma entidade do mundo real (uma referência a um local da memória que possui um valor), cada um com uma identidade – ou seja, dois objetos são distintos mesmo que eles apresentem exatamente as mesmas caraterísticas. A identificação do objeto deve ser única, uniforme e independente do seu conteúdo. Esse objeto pode ser uma variável (capaz de reter e representar um valor ou expressão), função (porção de código que resolve um problema específico) ou estrutura de dados (modo particular de armazenamento e organização de dados).

A estrutura de um objeto é representada em termos de atributos (propriedades). Podem ser divididos em atributos de instância (seus valores determinam o estado de cada objeto) ou atributos de classe (estado que é compartilhado por todos os objetos de uma classe). O comportamento de um objeto é representado pelo conjunto de operações que podem ser executadas sobre o objeto – quando possuem a mesma estrutura e o mesmo comportamento são agrupados em classes.

A classe é uma abstração que descreve propriedades importantes para uma aplicação de um conjunto de objetos individuais. Cada objeto é uma instância dessa classe, ou seja, sua concretização – uma classe é como um “molde” que gera instâncias de um certo tipo; um objeto é algo que existe fisicamente e que foi “moldado” na classe. Portanto, cada classe determina o comportamento (definido nos métodos, ou seja, as habilidades e ações possíveis) e estados possíveis (atributos) de seus objetos, assim como o relacionamento com outros objetos.

Um método é a implementação de uma operação para uma certa classe. A mesma operação pode se comportar de forma diferente em classes diferentes e pode ser implementada por mais de um método: isso é chamado polimorfismo. O objeto possui atributos e os métodos que determinam o seu “comportamento” (explicitado pelas interfaces).

Herança é o mecanismo que permite compartilhar atributos e operações entre classes baseada em um relacionamento hierárquico. Uma classe pode ser definida de forma genérica e depois refinada sucessivamente em subclasses, onde cada subclasse incorpora (herda) todas as propriedades de sua classe base e adiciona suas propriedades únicas e particulares.

Aplicação dos conceitos na linguagem python

Veja essa sequência de comandos em python a partir da definição de uma lista com elementos inteiros, ponto flutuante, string, booleano e outra lista. O objetivo é criar uma segunda lista igual à primeira e substituir o primeiro elemento da “lista dentro da lista”, mas mantendo a lista original intacta:

lista1 = [1,2,3.14,'abc',True,[4,5,6]]
lista2 = lista1
lista2[-1][0] = 10
print lista1
print lista2

Se não fosse linguagem orientada a objeto, realmente a variável lista2 receberia o conteúdo de lista1 e a alteração do primeiro elemento de lista2 teria ocorrido, e não em lista1. No entanto, em python, tudo são objetos, inclusive uma lista; lista1 e lista2 são apenas rótulos que apontam para o objeto “[1,2,3.14,’abc’,True,[4,5,6]]”. Para conferir isso, basta executar o comando print(id(lista1) == id(lista2)) e verificar que é impresso o booleano True (ou seja, a id é a mesma).

Quando é atribuído um objeto a outro, apenas se está copiando a referência à lista, e não seu conteúdo. Nesse caso, lista2 funciona como um apelido de lista1. Para copiar o conteúdo (usando outro espaço na memória), deve-se alterar a atribuição da segunda linha pelo seguinte comando:

lista2 = lista1[:]

Uma lista (“list”) é um objeto mutável: seu estado pode ser modificado após ser criado. Já uma tupla (“tuple”) é um objeto imutável, ou seja, se tentar mudar algum elemento, resultará em erro. Além disso, a diferença com relação à lista é que sua atribuição de elementos usa parênteses () em vez de colchetes []. Um conjunto (onde a ordem não interfere – não suporta indexificação – e não são admitidos elementos repetidos) possui os elementos separados por vírgulas dentro de chaves {}.

Por fim, um dicionário também é um objeto mutável, mas com propriedades de acesso diferentes. É composto por um conjunto de chaves e valores: se quer um valor, pergunta pela chave. Por exemplo, um dicionário onde as chaves (“keys”) sejam os nomes de pessoas e os valores (“values”) são as idades delas:

d = {'Marcos':28, 'Maria':34, 'Pedro':18}
print(d['Marcos'])

A segunda linha imprime a idade de Marcos. As chaves que são usadas como os índices da lista. No entanto, se a chave não existir, ela será adicionada ao dicionário, diferentemente do que acontece na lista, que diz que o índice não existe (fora do range do vetor).

Veja esse exemplo da classe “Pessoa” definida em python, com funções associadas a elas (chamadas então de métodos). Ela usa o método init (o duplo underline é chamado de “Dunder”, de “Double UNDERscore”); primeiro parâmetro sempre é self (por definição), que pode ser entendido como uma referência ao objeto em si recém-criado que precisa ser iniciado (utilizado para acessar qualquer atributo da instância). No caso, init é um construtor que associa um rótulo ao objeto. Na última linha, existe uma instância passando alguns atributos (p.nome e p.idade).

class Pessoa:

	def __init__(self, nome, idade):
		self.nome = nome
		self.idade = idade

p = Pessoa('marcos', 28)

A palavra class é executada pelo interpretador quando encontrada no código, e o resultado dessa execução é um novo objeto existente no escopo do módulo. Ou seja, class é um construtor de objetos do tipo “type”. Já a palavra def também cria objetos do tipo “function”. Os métodos/funções também são atributos. Veja mais sobre Python clicando no link.

Aplicação dos conceitos na linguagem IDL

Na linguagem IDL, os objetos (ou entidades) tem propriedades associadas a ele, como “color”, “line style”, “size”, etc. Por exemplo, você pode definir as propriedades na inicialização de um objeto da seguinte forma utilizando o par propriedade-valor:

> Obj = OBJ_NEW('ObjectClass', PROPERTY = value, ... )

Se o objeto herda da classe IDL_Object, você pode definir ou alterar as propriedades do objeto após sua inicialização chamando diretamente a propriedade utilizando o operador ponto:

> Obj.PROPERTY = value, ...

ou chamando o método “SetProperty” com sua propriedade-valor:

> Obj.SetProperty, PROPERTY = value, ...

onde “PROPERTY” é o nome da propriedade do objeto e “value” é o valor associado da propriedade. Se o objeto herda da classe IDL_Object, você pode recuperar os valores da propriedade chamando-a diretamente com o operador ponto (linha de cima) ou chamando o método “SetProperty” com sua propriedade-valor (linha de baixo):

> variable = Obj.PROPERTY
> Obj.GetProperty, PROPERTY = variable, ...

Obs: os pares propriedade-valor tem o mesmo comportamento que os pares chave-valor, ou seja, você pode definir o valor de uma propriedade booleana como 1 precedendo o nome da propriedade com um caractere de barra “/”. Veja as formas equivalentes:

> Obj.MYPROPERTY = 1
> Obj.SetProperty, MYPROPERTY = 1
> Obj.SetProperty, /MYPROPERTY

Para obter o valor de uma propriedade, você pode usar o operador ponto (se o objeto herda de IDL_Object) ou chamar o método GetProperty do objeto. Veja o exemplo:

> plotcolor = myPlot.COLOR
> myPlot.GetProperty, COLOR = plotcolor

O valor da propriedade “COLOR” é devolvido na variável “plotcolor”. Veja um exemplo de como acessar (definir ou obter) propriedades de objetos aninhados:

> p = PLOT(/TEST, TITLE="My Plot")
> ax = p.AXES
> ax[3].COLOR= 'red'

No objeto “ax” (um vetor), seu quarto elemento é obtido e “SetProperty, COLOR=’red'” é definido pelo objeto. Veja outro exemplo:

> PRINT, p.TITLE.STRING

Para o objeto p, GetProperty é chamada para obter o objeto “TITLE”, e então GetProperty é chamada no objeto título para obter o valor da string do título.

Ao acessar métodos e propriedades de uma classe, você pode usar o operador seta (->), com a seguinte sintaxe: Objeto->[Classe::]Método [, PROPRIEDADE=variável]

Abstração e encapsulação

As duas ações são importantes para o desenvolvimento de sistemas. Abstração consiste de focalizar nos aspectos essenciais inerentes a uma entidade (concentrar no que o objeto é e faz) antes de se decidir como ele será implementado. A encapsulação consiste em separar os aspectos externos de um objeto (acessíveis a outros objetos) dos detalhes internos de implementação do objeto (escondidos dos outros objetos), o que evita as partes de um programa tornarem-se tão interdependentes que uma pequena mudança tenha grandes efeitos colaterais.

Fontes

Wikipedia, UNICAMP, Exelis e Blog Etílico.

Compartilhe :)

One comment

Leave a Reply

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.