Baixe o app para aproveitar ainda mais
Prévia do material em texto
Programação Orientada a Objetos em C++ Profa. Dra. Ieda Hidalgo E-mail: iedahidalgo@ft.unicamp.br Introdução, Motivação e Conceitos Iniciais Introdução Código Objeto – C++ No caso de C++, a saída do compilador é um código de máquina específico para um SO e executado diretamente pela CPU. Para rodar um programa em C++ em um sistema diferente, é preciso recompilá-lo em um código de máquina voltado para aquele ambiente. Ou seja, para uma variedade de ambientes, são necessárias diversas versões executáveis do programa em C++. Código Objeto – Java e C# No caso de Java e C#, a saída do compilador é uma linguagem intermediária de pseudocódigo (bytecode para Java e MSIL para C#). Em ambos os casos, este pseudocódigo é executado por um sistema de tempo de execução que deve estar instalado na máquina. Para Java este pseudocódigo é executado por uma JVM (Java Virtual Machine). Para C#, o pseudocódigo é executado por uma CLR (Common Language Runtime). Portabilidade x Eficiência Como os sistemas de tempo de execução de Java e C# se encontram entre um programa e a CPU, são necessários códigos extras para programas em Java e C#. Por isto, programas em C++ normalmente rodam mais rápido do que programas equivalentes escritos em Java ou C#. Motivação Quando os computadores foram inventados (década de 40), a programação era feita no painel frontal do computador alternando as Instruções Binárias de máquina. Os programas foram crescendo e a Linguagem Assembly foi inventada (década de 50). Os programas continuaram crescendo e as Linguagens de Alto Nível foram desenvolvidas para dar aos programadores mais ferramentas para tratar a complexidade dos programas. A partir dos anos 60, com as Linguagens Estruturadas, foi possível escrever programas moderadamente complexos com grande facilidade. No entanto, no fim da década de 60, um conjunto de problemas no desenvolvimento de sistemas levou os países desenvolvidos à chamada “Crise do Software”. Ausência de uma metodologia para a construção de programas e ao rápido avanço tecnológico na fabricação dos equipamentos. Exigência crescente dos usuários tem forçado a indústria de software a estabelecer um acelerado ritmo de produtividade e de melhoria da qualidade de seus sistemas. Esta pressão tem tornado os sistemas cada vez maiores e mais complexos. Daí a motivação para o desenvolvimento da Programação Orientada a Objetos que surgiu no final dos anos 70, início dos anos 80. Aplicações Usando a POO um programador pode tratar programas muito grandes e complexos, com tempo de desenvolvimento rápido, maior índice de reaproveitamento do código e maior facilidade de manutenção dos sistemas. São exemplos de sistemas complexos: centrais telefônicas, banco de dados e sistemas distribuídos, controle de trens, controle de tráfego aéreo, etc. Conceitos Iniciais C++ Linguagem Símula Linguagem C A principal diferença entre a Programação Estruturada e a Programação Orientada a Objetos está na forma como dados e procedimentos se relacionam Conceitos Relacionados � Abstração � Encapsulamento � Herança � Polimorfismo � Modularidade Abstração Abstração é um meio pelo qual evitamos a complexidade não desejada. Observamos o domínio de um problema e focamos nos elementos que são relevantes para uma aplicação específica. O problema passa a ser representado não mais na linguagem do domínio, e sim na linguagem da solução. O principal objetivo da abstração é reduzir a complexidade do problema. Exemplo Suponha o problema de encontrar a rota ótima para um caminhão que recolhe lixo em uma cidade. A partir de um mapa da cidade podemos eliminar rios, praças, ... e traçar um grafo cujas arestas são os logradouros e os vértices são as esquinas. Sobre esta abstração do domínio aplica-se um algoritmo de solução (ex: carteiro chinês). Ao final, a linguagem não é mais a do mapa, e sim a do grafo que formaliza a solução. Encapsulamento A propriedade de se implementar dados e procedimentos correlacionados em uma mesma entidade (objeto) dá-se o nome de encapsulamento. A idéia é a de que a utilização de um sistema orientado a objetos não deve depender de sua implementação interna, e sim de sua interface. O principal objetivo do encapsulamento é proteger as características de um objeto contra alterações indevidas, mantendo a integridade do objeto. Exemplo Podemos entender intuitivamente o significado de encapsulamento observando o mundo real. No mundo real, atributos e ações são inerentes ao próprio objeto. Por exemplo, a um automóvel estão associados tanto atributos (modelo, cor e número máximo de passageiros) como suas potencialidades (locomoção e consumo de combustível). Herança A POO fornece uma maneira de relacionar classes por meio de uma hierarquia usando o conceito de herança. A classe de origem é chamada classe-base e as classes que herdam as características de uma classe-base e acrescentam outras características são chamadas classes- derivadas. Então, as características comuns devem ficar na classe-base e cada classe-derivada é uma versão especializada da classe-base. Exemplo A classe-base animais é dividida nas classes- derivadas mamíferos, aves, peixes, etc. Uma das características da classe-base animais é a reprodução, logo, todas as classes-derivadas têm essa característica. Da mesma forma que você pode criar uma biblioteca de funções, você pode criar uma biblioteca de classes que poderão vir a ser o núcleo de muitos programas. O uso de biblioteca de classes oferece uma grande vantagem sobre o uso de biblioteca de funções: o programador pode criar classes-derivadas de classe-base de biblioteca. Isto significa que, sem alterar a classe-base, é possível adicionar a ela características diferentes que a tornarão capaz de executar exatamente o que desejamos. Além disso, o processo de teste da classe-base não precisa ser repetido. A uma função de biblioteca não podemos adicionar outras implementações a não ser que ela seja reescrita ou que tenhamos seu código-fonte para alterá-la e recompilá-la. Para usar uma classe ou mesmo para derivar uma classe, você só precisa ter o arquivo de código-objeto ou uma biblioteca que contenha seu código-objeto, você não precisa do código-fonte. Isto permite que bibliotecas de classes sejam compradas, distribuídas e adaptadas facilmente. Polimorfismo O termo polimorfismo origina-se do grego. O significado da palavra é "muitas formas". Na análise orientada a objetos, ele é usado para indicar a propriedade de se usar o mesmo nome para métodos (funções-membro) diferentes, implementados em diferentes níveis de uma hierarquia de classes. Para que haja polimorfismo é necessária a existência de ligação dinâmica, ou seja, a ligação objeto-função-membro deve ser feita apenas em tempo de execução. Exemplo Várias classes numa hierarquia definindo um método de impressão com o mesmo nome “print”, porém, em cada nível hierárquico pode haver um código diferente para o método. Um exemplo no mundo real é o fato de usarmos a operação de nome "on" em vários eletrodomésticos, computadores, máquinas, etc. Embora os nomes sejam idênticos, os procedimentos em cada situação são diferentes. Sobrecarga A sobrecarga é um tipo particular de polimorfismo (polimorfismo estático). Por exemplo, em C++, usamos o operador aritmético “+” para somar números inteiros ou reais. O computador executa operações completamente diferentes para somar números inteiros e números reais. A utilização de um mesmo símbolo para a execução de operações distintas é chamada sobrecarga de operadores. Além das sobrecargas embutidas na linguagem, podemos definir outras com capacidades novas. Existe também a sobrecargade métodos. Modularidade A modularidade leva a uma separação entre a interface e a implementação das classes. Os arquivos-cabeçalho, geralmente descritos com extensão “h” tradicionalmente guardam definições de classes e declarações de funções. A implementação dessas classes costuma ser colocada em arquivos com extensão “cpp”. As principais vantagens da modularização são: otimizar o processo de recompilação e permitir maior flexibilidade e eficiência na implementação do sistema.
Compartilhar