sábado, 15 de fevereiro de 2014

Desenvolvimento Orientado à Objeto



Apresento algumas definições dos mecanismos da POO (programação orientada à objeto). Um dos grandes diferenciais da programação orientada a objetos em relação a outros paradigmas de programação está no conceito de herança, mecanismo através do qual definições existentes podem ser facilmente estendidas. Juntamente com a herança deve ser enfatizada a importância do polimorfismo, que permite selecionar funcionalidades que um programa irá utilizar de forma dinâmica, durante sua execução.


apresentaremos algumas definições dos mecanismos da POO. Um dos grandes diferenciais da programação orientada a objetos em relação a outros paradigmas de programação está no conceito de herança, mecanismo através do qual definições existentes podem ser facilmente estendidas. Juntamente com a herança deve ser enfatizada a importância do polimorfismo, que permite selecionar funcionalidades que um programa irá utilizar de forma dinâmica, durante sua execução.

O PARADIGMA POO 

Programação orientada a objetos (POO) é uma metodologia de programação adequada ao desenvolvimento de sistemas de grande porte, provendo modularidade e reusabilidade. A POO introduz uma abordagem na qual o programador visualiza seu programa em execução como uma coleção de objetos cooperantes que se comunicam através de mensagens. Cada um dos objetos é instância de uma classe e todas as classes formam uma hierarquia de classes unidas via relacionamento de herança. Existem alguns aspectos importantes na definição de POO:

  Usa objetos, e não funções ou procedimentos como seu bloco lógico fundamental de construção de programas

  Objetos comunicam-se através de mensagens

  Cada objeto é instância de uma classe

  Classes estão relacionadas com as outras via mecanismos de herança

            Programação orientada a objetos dá ênfase à estrutura de dados, adicionando funcionalidade ou capacidade de processamento a estas estruturas. Em linguagens tradicionais, a importância maior é atribuída a processos, e sua implementação em subprogramas. Em uma linguagem como Pascal, procedimentos ativos agem sobre dados passivos que foram passados a eles. Em linguagens orientadas a objetos, ao invés de passar dados a procedimentos, requisita-se que objetos realizem operações neles próprios.
            Alguns aspectos são fundamentais na definição de programação orientada a objetos, que serão devidamente investigados neste trabalho:

  Abstração de dados

  Objetos

  Mensagens

  Classes

  Herança

  Polimorfismo

Objeto
                                                                                                                          
            Na visão de uma linguagem imperativa tradicional (Pascal, C, COBOL, etc.), os objetos aparecem como uma única entidade autônoma que combina a representação da informação (estruturas de dados) e sua manipulação (procedimentos), uma vez que possuem capacidade de processamento e armazenam um estado local. Pode-se dizer que um objeto é composto de:

  Propriedades: são as informações, estruturas de dados que representam o estado interno do objeto. Em geral, não são acessíveis aos demais objetos.

  Comportamento: conjunto de operações, chamados de métodos, que agem sobre as propriedades. Os métodos são ativados (disparados) quando o objeto recebe uma mensagem solicitando sua execução. Embora não seja obrigatório, em geral uma mensagem recebe o mesmo nome do método que ela dispara. O conjunto de mensagens que um objeto está apto a receber está definido na sua interface.

  Identidade: é uma propriedade que diferencia um objeto de outro; ou seja, seu nome.

              Enquanto que os conceitos de dados e procedimentos são freqüentemente tratados separadamente nas linguagens de programação tradicionais, em POO eles são reunidos em uma única entidade: o objeto.

            No mundo real não é difícil a identificação de objetos (em termos de sistemas, objetos são todas as entidades que podem ser modeladas, não apenas os nossos conhecidos objetos inanimados). Como exemplo, em uma empresa pode-se identificar claramente objetos da classe empregado.

              Um empregado possui uma identidade própria, seu nome: José da Silva. Possui também propriedades como: endereço, idade, dependentes, salário, cargo, entre outras. O comportamento pode ser determinado por operações como: aumentar salário, listar dependentes e alterar cargo. As propriedades somente podem ser manipuladas através das operações definidas na interface do objeto, de modo que a forma de armazenamento das propriedades e a implementação das operações são desconhecidas pelas outras entidades externas (encapsulamento de informações).

 O objeto "Empregado"

  Benefícios proporcionados pelos objetos:

  Uma vez que objetos utilizam o princípio da abstração de dados, o encapsulamento de informação proporciona dois benefícios principais para o desenvolvimento de sistemas:

  Modularidade:
o código fonte para um objeto pode ser escrito e mantido independentemente da código fonte de outros objetos. Além disso, um objeto pode ser facilmente migrado para outros sistemas.
                                                                                                                                       
  Ocultamento de informação: um objeto tem uma interface pública que os outros objetos podem utilizar para estabelecer comunicação com ele. Mas, o objeto mantém informações e métodos privados que podem ser alterados a qualquer hora sem afetar os outros objetos que dependem dele. Ou seja, não é necessário saber como o objeto é implementado para poder utilizá-lo.

Mensagens

            Um objeto sozinho não é muito útil e geralmente ele aparece como um componente de um grande programa que contem muitos outros objetos. Através da interação destes objetos pode-se obter uma grande funcionalidade e comportamentos mais complexos.

            Objetos de software interagem e comunicam-se com os outros através de mensagens. Quando o objeto A deseja que o objeto B execute um de seus métodos, o objeto A envia uma mensagem ao objeto B. Algumas vezes o objeto receptor precisa de mais informação para que ele saiba exatamente o que deve fazer; esta informação é transmitida juntamente com a mensagem através de parâmetros.

  Uma mensagem é formada por três componentes básicos:

  o objeto a quem a mensagem é endereçada (receptor)

  o nome do método que se deseja executar

  os parâmetros (se existirem) necessários ao método

Classe

            "É a definição dos atributos e funções de um tipo de objeto. Cada objeto individual é então criado com base no que está definido na classe. Por exemplo, homo sapiens é um classe de mamífero; cada ser humano individual é um objeto dessa classe."

            Objetos de estrutura e comportamento idênticos são descritos como pertencendo a uma classe, de tal forma que a descrição de suas propriedades pode ser feita de uma só vez, de forma concisa, independente do número de objetos idênticos em termos de estrutura e comportamento que possam existir em uma aplicação. A noção de um objeto é equivalente ao conceito de uma variável em programação convencional, pois especifica uma área de armazenamento, enquanto que a classe é vista como um tipo abstrato de dados, uma vez que representa a definição de um tipo.

            Cada objeto criado a partir de uma classe é denominado de instância dessa classe. Uma classe provê toda a informação necessária para construir e utilizar objetos de um tipo, cada instância pertence a uma classe e uma classe pode possuir múltiplas instâncias. Devido ao fato de todas as instâncias de uma classe compartilharem as mesmas operações, qualquer diferença de respostas a mensagens aceitas por elas, é determinada pelos valores das variáveis de instância.

                                                                                                                                    
 Relacionamento entre classes e objetos

            O relacionamento entre classes e objetos. Cada objeto instanciado a partir de uma classe possui as propriedades e comportamento definidos na classe, da mesma maneira que uma variável incorpora as características do seu tipo. A existência de classes proporciona um ganho em reusabilidade. pois o código das operações e a especificação da estrutura de um número potencialmente infinito de objetos estão definidos em um único local, a classe. Cada vez que um novo objeto é instanciado ou que uma mensagem é enviada, a definição da classe é reutilizada. Caso não existissem classes, para cada novo objeto criado, seria preciso uma definição completa do objeto.

Metaclasses

            Uma metaclasse é uma classe de classes. Pode-se julgar conveniente que, em uma linguagem ou ambiente, classes também possam ser manipuladas como objetos. Por exemplo, uma classe pode conter variáveis contendo informações úteis, como:

  o número de objetos que tenham sido instanciados da classe até certo instante;

            um valor médio de determinada propriedade, calculado sobre os valores específicos desta propriedade nas instâncias (por exemplo, média de idade de empregados).

Benefícios proporcionados pelas classes:

            O maior benefício proporcionado pela utilização das classes é a reusabilidade de código, uma vez que todos os objetos instanciados a partir dela incorporam as suas propriedades e seu comportamento.

Métodos

            Um método implementa algum aspecto do comportamento do objeto. Comportamento é a forma como um objeto age e reage, em termos das suas trocas de estado e troca de mensagens.

            Um método é uma função ou procedimento que é definido na classe e tipicamente pode acessar o estado interno de um objeto da classe para realizar alguma operação. Pode ser pensado como sendo um procedimento cujo primeiro parâmetro é o objeto no qual deve trabalhar. Este objeto é chamado receptor. Abaixo é apresentada uma notação possível para o envio de uma mensagem (invocação do método)

            Construtores são usados para criar e inicializar objetos novos. Tipicamente, a inicialização é baseada em valores passados como parâmetros para o construtor. Destrutores são usados para destruir objetos. Quando um destrutor é invocado, as ações definidas pelo usuário são executadas, e então a área de memória alocada para o objeto é liberada. Em algumas linguagens, como C++, o construtor é chamado automaticamente quando um objeto é declarado. Em outras, como Object Pascal, é necessário chamar explicitamente o construtor antes de poder utilizá-lo.
                                                                                                                        

            Um exemplo de utilização de construtores e destrutores seria gerenciar a quantidade de objetos de uma determinada classe que já foram criados até o momento. No construtor pode-se colocar código para incrementar uma variável e no destrutor o código para decrementá-la.


O QUE É HERANÇA E QUAL A SUA APLICAÇÃO


Herança

            O conceito de herança é fundamental na técnica de orientação a objetos. A herança permite criar um novo tipo de objeto - uma nova classe - a partir de outra já existente.

            A nova classe mantém os atributos e a funcionalidade da classe da qual deriva; por isso, dizemos que ela "herda" as características daquela classe. Ao mesmo tempo, ela pode receber atributos e funções especiais não encontrados na classe original. Voltando ao exemplo da janela de um programa Windows, esse tipo de objeto poderia se chamar Janela. Ao criarmos um tipo de objeto para funcionar como caixa de diálogo é uma janela com atributos especiais, como a exibição de botões e opções.

            O novo tipo poderia se chamar JanelaDiálogo e herdaria as características da classe Janela, recebendo também os atributos exclusivos de uma caixa de diálogo.
Uma das vantagens da herança é a facilidade de localizar erros de programação. Por exemplo, caso um objeto derivado de outro apresente um erro de funcionamento; se o objeto original funcionava corretamente, é claro que o erro está na parte do código que implementa as novas características do objeto derivado. A herança permite, também, reaproveitar o código escrito anteriormente, adaptando-o às novas necessidades.
            Isso é muito importante porque os custos de desenvolvimento de software são muitos elevados. A mão-de-obra altamente especializada é cara; o processo é demorado e sujeito a ocorrências inesperadas.


            A herança é um relacionamento pelo qual uma classe, chamada de sub-classe, herda todos comportamentos e estados possíveis de outra classe, chamada de super-classe ou classe base. É permitido que a sub-classe estenda os comportamentos e estados possíveis da super-classe (por isso este relacionamento também é chamado de extensão). Essa extensão ocorre adicionando novos membros a sub-classe, como novos métodos e atributos.
            É também possível que a sub-classe altere os comportamentos e estados possíveis da super-classe. Neste caso, a sub-classe sobrescreve membros da super-classe, tipicamente métodos.
            Quando uma classe herda de mais de uma super-classe, ocorre uma herança múltipla. Esta técnica é possível em C++ e em Python, mas não é possível em Java e C#, no entanto estas linguagens permitem múltipla tipagem através do uso de interfaces.



                                                                                                                                  


Representação de herança entre classes em UML


            A Herança é um princípio da Programação Orientada a Objetos que permite que as classes compartilhem atributos e operações baseados em um relacionamento, geralmente generalização. A herança permite a criação de subclasses que herdam alguns dos atributos e das operações (ou Métodos) da classe pai (super-classe ou classe base). A herança é um conceito aplicado no momento de criação das classes. Ela é usada na intenção de reaproveitar código ou comportamento generalizado ou especializar operações ou atributos.
            Como exemplo pode-se observar as classes 'aluno' e 'professor', onde ambas possuem atributos como nome, endereço e telefone. Nesse caso pode-se criar uma nova classe chamada por exemplo, 'pessoa', que contenha as semelhanças entre as duas classes, fazendo com que aluno e professor herdem as características de pessoa, desta maneira pode-se dizer que aluno e professor são subclasses de pessoa.
            A 'Herança Múltipla, implementado em algumas linguagens de programação orientadas a objetos, que possibilita o compartilhamento de atributos e operações de duas ou mais classes em uma subclasse.
            Ela é implementada nas linguagens de programação C++ e em Python, por exemplo. A linguagem Java possui apenas herança simples (uma classe possui no máximo uma classe pai), mas permite que uma classe implemente várias interfaces.
            O uso indiscriminado desta característica pode levar a uma codificação confusa que dificultaria a manutenção do código.
            A tecnologia Java, não dá suportes a heranças múltiplas.
            Herança é a capacidade de uma subclasse de ter acesso as propriedades da superclasse a ela relacionada.
             Dessa forma as propriedades de uma classe são propagadas de cima para baixo em um diagrama de classes. Neste caso dizemos que a subclasse herda as propriedades e métodos da superclasse
            A relação de herança entre duas classes é uma relação da seguinte forma: A “e um tipo de” B, onde A e B são classes. Caso esta relação entre as classes não puder ser construída, em geral, também não se tem uma relação de herança entre a classe A  a partir da classe B.
            Exemplos: Um Carro de Passeio “é um tipo de ” veículo; Um caminhão “é um tipo de” veículo; Um círculo “é um tipo de” uma figura geométrica; Um quadrado “é um tipo de” figura geométrica; Um vendedor “é um tipo de” Empregado; Um empregado “e um tipo de” pessoa.
            Herança Múltipla – Uma subclasse herda características de mais uma classe
             Exemplos: Um gerente de vendas “é um tipo” de vendedor e “é um tipo de” gerente; Além da relação de herança entre as classes existe a relação de uso  HERANÇA classe A “é
um tipo de" B.
USO / AGREGAÇÃO (Relação de Conteúdo)
classe D “contém” classe C”
classe D “usa” classe C”
classe C “é parte da” classe D
Exemplo: Uma equipe contém um gerente e um grupo de vendedores.  


O QUE É E QUANDO OCORRE O POLIMORFISMO

            Polimorfismo é o princípio pelo qual duas ou mais classes derivadas de uma mesma superclasse podem invocar métodos que têm a mesma identificação (assinatura) mas comportamentos distintos, especializados para cada classe derivada, usando para tanto uma referência a um objeto do tipo da superclasse. A decisão sobre qual o método que deve ser selecionado, de acordo com o tipo da classe derivada, é tomada em tempo de execução, através do mecanismo de ligação tardia.

            No caso de polimorfismo, é necessário que os métodos tenham exatamente a mesma identificação, sendo utilizado o mecanismo de redefinição de métodos. Esse mecanismo de redefinição não deve ser confundido com o mecanismo de sobrecarga de métodos.

            O uso de polimorfismo em Java é ilustrado através de um exemplo. Através desse exemplo introduzem-se os conceitos relacionados de upcasting e a motivação para a definição de métodos abstratos.

            É importante observar que, quando polimorfismo está sendo utilizado, o comportamento que será adotado por um método só será definido durante a execução. Embora em geral esse seja um mecanismo que facilite o desenvolvimento e a compreensão do código orientado a objetos, há algumas situações onde o resultado da execução pode ser não-intuitivo, como ilustra esse exemplo que usa polimorfismo em construtores.

            Na programação orientada a objetos, o polimorfismo permite que referências de tipos de classes mais abstratas representem o comportamento das classes concretas que referenciam. Assim, um mesmo método pode apresentar várias formas, de acordo com seu contexto. O polimorfismo é importante pois permite que a semântica de uma interface seja efetivamente separada da implementação que a representa. O termo polimorfismo é originário do grego e significa "muitas formas" (poli = muitas, morphos = formas).

            O Polimorfismo ocorre quando um programa invoca uma função virtual por meio de um ponteiro de classe básica ou referência.
            Polimorfismo permite programar no geral em vez de programar no específico, escrevendo programas que processam objetos de classes que fazem parte da mesma hierarquia de classes como se todos fossem objetos da classe básica da hierarquia. A mesma mensagem enviada a uma variedade de objetos tem “muitas formas” de resultado. Tipo polimórfico é tipo com funções virtuais.
 


Nenhum comentário:

Postar um comentário

O que achou dessa postagem?