top of page
java-oops.png

   Fundamentos da programação orientada a objetos

  1. Fundamentos da programação orientada a objetos                                                            3

    1. Classes...................................................................................................................... 3

    2. Objetos...................................................................................................................... 4

    3. Herança..................................................................................................................... 6

    4. Polimorfismo............................................................................................................. 6

  2. Princípios da programação na linguagem Java                                                                  8

    1. Tipos primitivos......................................................................................................... 8

    2. Identificadores......................................................................................................... 10

    3. Expressões............................................................................................................... 11

      1. Expressões retornando valores numéricos....................................................... 11

      2. Expressões retornando valores booleanos....................................................... 12

      3. Outros tipos de expressões............................................................................ 13

      4. Controle do fluxo de execução....................................................................... 13

      5. Comentários................................................................................................. 15

    4. Operações sobre objetos........................................................................................... 16

      1. Arranjos....................................................................................................... 18

      2. Strings......................................................................................................... 19

    5. Classes em Java........................................................................................................ 20

      1. Pacotes........................................................................................................ 20

      2. Definição de classes em Java......................................................................... 21

      3. O método main........................................ 24

      4. Visibilidade da classe e seus membros........................................................... 25

      5. Classes derivadas.......................................................................................... 25

      6. Classes abstratas e finais............................................................................... 27

      7. Interfaces..................................................................................................... 28

    6. Exceções................................................................................................................. 29

      1. Tratamento de exceções................................................................................ 30

      2. Erros e exceções de runtime.......................................................................... 31

      3. Propagando exceções.................................................................................... 32

      4. Definindo e gerando exceções........................................................................ 32

    7. O ambiente de Java................................................................................................... 33

      1. Ferramentas do Java SDK.............................................................................. 34

      2. Geração de código portátil............................................................................. 34

      3. Desenvolvimento de aplicações..................................................................... 35

  3. Uso das classes da API padrão de Java                                                                             37

    1. Funcionalidades básicas............................................................................................ 37

    2. Entrada e saída......................................................................................................... 38

      1. Transferência de texto................................................................................... 39

      2. Transferência de bytes.................................................................................. 40

      3. Manipulação de arquivos............................................................................... 41

      4. Serialização.................................................................................................. 42

    3. Framework de coleções............................................................................................. 43

    4. Extensões padronizadas............................................................................................ 45

  4. Desenvolvimento de aplicações gráficas                                                                           46

    1. Apresentação gráfica................................................................................................ 46

    2. Interfaces gráficas com usuários................................................................................ 47

      1. Eventos da interface gráfica........................................................................... 47

      2. Componentes gráficos................................................................................... 50

      3. Containers................................................................................................... 54

      4. Janelas......................................................................................................... 55

      5. Gerenciadores de layout................................................................................ 57

    3. Desenvolvimento de applets...................................................................................... 65

      1. Criação de applet.......................................................................................... 66

      2. Execução de applets...................................................................................... 67

      3. Passagem de parâmetros................................................................................ 68

      4. Contexto de execução................................................................................... 69

  5. Desenvolvimento de aplicações distribuídas                                                                     72

    1. Programação cliente-servidor.................................................................................... 72

      1. Conceitos preliminares.................................................................................. 73

      2. Aplicações TCP/IP....................................................................................... 75

      3. Aplicações UDP........................................................................................... 79

      4. Aplicações HTTP......................................................................................... 81

    2. Acesso a bancos de dados......................................................................................... 83

      1. Bancos de dados relacionais.......................................................................... 84

      2. SQL............................................................................................................. 85

      3. JDBC........................................................................................................... 87

    3. Servlets................................................................................................................... 90

      1. Ciclo de vida de um servlet........................................................................... 91

      2. Fundamentos da API de servlets.................................................................... 92

    4. Programação com objetos distribuídos....................................................................... 94

      1. Arquiteturas de objetos distribuídos............................................................... 94

      2. Java RMI..................................................................................................... 96

      3. Java IDL.................................................................................................... 113

A   Palavras chaves de Java                                                                                                 117

func x oop.jpg

Fundamentos da programação orientada a objetos

Neste capítulo são apresentados os conceitos básicos que permeiam o uso das técnicas de orientação a objetos na programação, sempre utilizando a linguagem Java como motivador. Objetos são instâncias de classes, que determinam qual informação um objeto contém e como ele pode manipulá-la. Um dos grandes diferenciais da programação orientada a objetos em relação a outros paradigmas de programação que também permitem a definição de estruturas e operações sobre essas estruturas 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.

Classes

A definição de classes e seus inter-relacionamentos é o principal resultado da etapa de projeto de software. Em geral, esse resultado é expresso em termos de alguma linguagem de modelagem, tal como UML.

Uma classe é um gabarito para a definição de objetos. Através da definição de uma classe, descreve-se que propriedades — ou atributos — o objeto terá.

Além da especificação de atributos, a definição de uma classe descreve também qual o comportamento de objetos da classe, ou seja, que funcionalidades podem ser aplicadas a objetos da classe. Essas funcionalidades são descritas através de métodos. Um método nada mais é que o equivalente a um procedimento ou função, com a restrição que ele manipula apenas suas variáveis locais e os atributos que foram definidos para a classe.

Uma vez que estejam definidas quais serão as classes que irão compor uma aplicação, assim como qual deve ser sua estrutura interna e comportamento, é possível criar essas classes em Java.

Na Unified Modeling Language (UML), a representação para uma classe no diagrama de classes é tipicamente expressa na forma gráfica, como mostrado na Figura 1.1.

Como se observa nessa figura, a especificação de uma classe é composta por três regiões: o nome da classe, o conjunto de atributos da classe e o conjunto de métodos da classe.

NomeClasse

visibilidade nomeAtributo : tipo = valor default

...

visibilidade nomeAtributo : tipo = valor default

visibilidade nomeMétodo(listaArgumentos) : tipoRetorno

...

visibilidade nomeMétodo(listaArgumentos) : tipoRetorno

 

O nome da classe é um identificador para a classe, que permite referenciá-la posteriormente — por exemplo, no momento da criação de um objeto. O conjunto de atributos descreve as propriedades da classe. Cada atributo é identificado por um nome e tem um tipo associado. Em uma linguagem de programação orientada a objetos pura, o tipo é o nome de uma classe. Na prática, a maior parte das linguagens de programação orientada a objetos oferecem um grupo de tipos primitivos, como inteiro, real e caráter, que podem ser usados na descrição de atributos. O atributo pode ainda ter um valor_default opcional, que especifica um valor inicial para o atributo.

Os métodos definem as funcionalidades da classe, ou seja, o que será possível fazer com objetos dessa classe. Cada método é especificado por uma assinatura, composta por um identificador para o método (o nome do método), o tipo para o valor de retorno e sua lista de argumentos, sendo cada argumento identificado por seu tipo e nome.

Através do mecanismo de sobrecarga (overloading), dois métodos de uma classe podem ter o mesmo nome, desde que suas assinaturas sejam diferentes. Tal situação não gera conflito pois o compilador é capaz de detectar qual método deve ser escolhido a partir da análise dos tipos dos argumentos do método. Nesse caso, diz-se que ocorre a ligação prematura (early binding) para o método correto.

O modificador de visibilidade pode estar presente tanto para atributos como para métodos. Em princípio, três categorias de visibilidade podem ser definidas:

público, denotado em UML pelo símbolo +:

     nesse caso, o atributo ou método de um objeto dessa classe pode ser acessado por qualquer outro objeto         (visibilidade externa total);

privativo, denotado em UML pelo símbolo -:

     nesse caso, o atributo ou método de um objeto dessa classe não pode ser acessado por nenhum outro               objeto (nenhuma visibilidade externa);

protegido, denotado em UML pelo símbolo #:

     nesse caso, o atributo ou método de um objeto dessa classe poderá ser acessado apenas por objetos de           classes que sejam derivadas dessa através do mecanismo de herança (ver Seção 1.3).

Objetos

Objetos são instâncias de classes. É através deles que (praticamente) todo o processamento ocorre em sistemas implementados com linguagens de programação orientadas a objetos. O uso racional de objetos, obedecendo aos princípios associados à sua definição conforme estabelecido no paradigma de desenvolvimento orientado a objetos, é chave para o desenvolvimento de sistemas complexos e eficientes.

Um objeto é um elemento que representa, no domínio da solução, alguma entidade (abstrata ou concreta) do domínio de interesse do problema sob análise. Objetos similares são agrupados em classes.

 

No paradigma de orientação a objetos, tudo pode ser potencialmente representado como um objeto. Sob o ponto de vista da programação orientada a objetos, um objeto não é muito diferente de uma variável normal. Por exemplo, quando define-se uma variável do tipo int em uma linguagem de programação como C ou Java, essa variável tem:

um espaço em memória para registrar o seu estado (valor);

um conjunto de operações que podem ser aplicadas a ela, através dos operadores definidos na linguagem que podem ser aplicados a valores inteiros.

Da mesma forma, quando se cria um objeto, esse objeto adquire um espaço em memória para armazenar seu estado (os valores de seu conjunto de atributos, definidos pela classe) e um conjunto de operações que podem ser aplicadas ao objeto (o conjunto de métodos definidos pela classe).

Um programa orientado a objetos é composto por um conjunto de objetos que interagem através de “trocas de mensagens”. Na prática, essa troca de mensagem traduz-se na aplicação de métodos a objetos.

As técnicas de programação orientada a objetos recomendam que a estrutura de um objeto e a implementação de seus métodos devem ser tão privativos como possível. Normalmente, os atributos de um objeto não devem ser visíveis externamente. Da mesma forma, de um método deve ser sufici- ente conhecer apenas sua especificação, sem necessidade de saber detalhes de como a funcionalidade que ele executa é implementada.

Encapsulação é o princípio de projeto pelo qual cada componente de um programa deve agregar toda a informação relevante para sua manipulação como uma unidade (uma cápsula). Aliado ao conceito de ocultamento de informação, é um poderoso mecanismo da programação orientada a objetos.

Ocultamento da informação é o princípio pelo qual cada componente deve manter oculta sob sua guarda uma decisão de projeto única. Para a utilização desse componente, apenas o mínimo necessário para sua operação deve ser revelado (tornado público).

Na orientação a objetos, o uso da encapsulação e ocultamento da informação recomenda que a representação do estado de um objeto deve ser mantida oculta. Cada objeto deve ser manipulado ex- clusivamente através dos métodos públicos do objeto, dos quais apenas a assinatura deve ser revelada. O conjunto de assinaturas dos métodos públicos da classe constitui sua interface operacional. Dessa forma, detalhes internos sobre a operação do objeto não são conhecidos, permitindo que o usuário do objeto trabalhe em um nível mais alto de abstração, sem preocupação com os detalhes in- ternos da classe. Essa facilidade permite simplificar a construção de programas com funcionalidades complexas, tais como interfaces gráficas ou aplicações distribuídas.

 

Herança

O conceito de encapsular estrutura e comportamento em um tipo não é exclusivo da orientação a objetos; particularmente, a programação por tipos abstratos de dados segue esse mesmo conceito. O que torna a orientação a objetos única é o conceito de herança. Herança é um mecanismo que permite que características comuns a diversas classes sejam fatoradas em uma classe base, ou superclasse. A partir de uma classe base, outras classes podem ser especificadas. Cada classe derivada ou subclasse apresenta as características (estrutura e métodos) da classe base e acrescenta a elas o que for definido de particularidade para ela.

 

Há várias formas de relacionamentos em herança:

Extensão: a subclasse estende a superclasse, acrescentando novos membros (atributos e/ou métodos). A superclasse permanece inalterada, motivo pelo qual este tipo de relacionamento é normalmente referenciado como herança estrita.

Especificação: a superclasse especifica o que uma subclasse deve oferecer, mas não implementa nenhuma funcionalidade. Diz-se que apenas a interface (conjunto de especificação dos métodos públicos) da superclasse é herdada pela subclasse.

Combinação de extensão e especificação: a subclasse herda a interface e uma implementação padrão de (pelo menos alguns de) métodos da superclasse. A subclasse pode então redefinir métodos para especializar o comportamento em relação ao que é oferecido pela superclasse, ou ter que oferecer alguma implementação para métodos que a superclasse tenha declarado mas não implementado. Normalmente, este tipo de relacionamento é denominado herança polimórfica.

A última forma é, sem dúvida, a que mais ocorre na programação orientada a objetos.

Algumas modelagens introduzem uma forma de herança conhecida como contração. Contração é uma uma variante de herança onde a subclasse elimina métodos da superclasse com o objetivo de criar uma “classe mais simples”. A eliminação pode ocorrer pela redefinição de métodos com corpo vazio. O problema com este mecanismo é que ele viola o princípio da substituição, segundo o qual uma subclasse deve poder ser utilizada em todos os pontos onde a superclasse poderia ser utilizada. Se a contração parece ser uma solução adequada em uma hierarquia de classes, provavelmente a hierarquia deve ser re-analisada para detecção de inconsistências (problema pássaros-pinguins). De modo geral, o mecanismo de contração deve ser evitado.

 

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. Esse mecanismo é fundamental na programação orientada a objetos, permitindo definir funcionalidades que operem genericamente com objetos, abstraindo-se de seus detalhes particulares quando esses não forem necessários.

 

Para que o polimorfismo possa ser utilizado, é necessário que os métodos que estejam sendo definidos nas classes derivadas tenham exatamente a mesma assinatura do método definido na super-classe; nesse caso, está sendo utilizado o mecanismo de redefinição de métodos (overriding). Esse mecanismo de redefinição é muito diferente do mecanismo de sobrecarga de métodos, onde as listas de argumentos são diferentes.

No caso do polimorfismo, o compilador não tem como decidir qual o método que será utilizado se o método foi redefinido em outras classes — afinal, pelo princípio da substituição um objeto de uma classe derivada pode estar sendo referenciado como sendo um objeto da superclasse. Se esse for o caso, o método que deve ser selecionado é o da classe derivada e não o da superclasse.

Dessa forma, a decisão sobre qual dos métodos método que deve ser selecionado, de acordo com o tipo do objeto, pode ser tomada apenas em tempo de execução, através do mecanismo de ligação tardia. O mecanismo de ligação tardia também é conhecido pelos termos em inglês late binding, dynamic binding ou ainda run-time binding.

(c) FMK 2023 - 2024.  Updated Sep 2024.

bottom of page