sexta-feira, 3 de agosto de 2012

Aula 1 - Mundo Java e Abstração

Daremos início ao curso de Java a partir desse material on-line.

Introdução (onde vamos chegar?)
É preciso saber que almejar entender tudo sobre Java após a conclusão de um curso é ficção. No geral alcaçaremos algo em torno de 10% do que uma API poderosa, como a do Java, tem a oferecer para os programadores.
Mas isso não quer dizer que você, leitor, após o acompanhamento das aulas, possa por conta própria evoluir e dar continuidade no aprendizado. Espero que ao final do curso você fique preparado para caminhar sozinho através de livros e papers sobre o assunto.

Trabalhar com Java sem UML e uma boa IDE, na prática, não existe! Diante dessa afirmação eventualmente estaremos tratando de itens da UML 2.0 e como manipular a ferramenta de desenvolvimento Eclipse. De ínicio, confesso que não usaremos nada (eu disse... NADA!) do Eclipse. “Faremos tudo na mão!”. Depois que estivermos habituados a trabalhar com a linguagem, aplicaremos nossos conhecimentos através do Eclipse.

Bom, diante disso, caso queira continuar nessa aventura, siga para o próximo passo.
Obs. Estou redigindo esse material em conjunto com um grupo de esutdo de Java que está sendo realizado no trabalho (é isso mesmo Ludmilla, Sirley e Walmir, esse material é para nós caminharmos juntos). Vou utilizar a sequência que trabalharmos nesse grupo, variando os objetos de estudo de acordo com o avanço dos tópicos tratados em aula.

Um pouco sobre Java
Java é uma linguagem de programação interpretada e totalmente orientada a objetos.
Tá certo! Vamos devagar então...

Por interpretada, entenda que:
Um programa Java não roda diretamente sob o SO (sistema operacional). O Java foi concebido para ser multi-plataforma. Para isso, quando se quer rodar um programa Java numa máquina qualquer, antes de mais nada, deve ser instalado no SO a Máquina Virtual Java - mais conhecida na noite carioca como JVM.

Mas afinal, o que é uma JVM?
É o interpretador capaz de “ler” os programas em Java e “solicitar” ao computador as operações definidas nesses programas. Isso significa que, se tivermos uma JVM no Linux e outra no Windows, um mesmo programa poderá ser interpretado nessas duas plataformas distintas, sem haver a necessidade de recompilação do programa.

Puxa! Mais isso tornará meu programa mais lento, não?
Claro que vai. Mas há 10 anos atrás, poderíamos dizer: nossa, como um programa Java é mais lento que um programa em C++! Hoje meu amigo, com as altíssimas frequências das CPUs e grandes quantidades de memória principal, esse não é mais um problema quando levamos em consideração as grandes vantagens de se trabalhar com o Java.

Como funciona um programa em Java?


Primeiramente precisamos saber que os fontes dos programas em Java são criados em arquivos com a extensão .java. Um arquivo poderá conter uma ou mais classes (veremos mais detalhes sobre classes adiante). Enfim, quando se fala em código fonte se fala em um arquivo de texto simples com a extensão .java.
Mesmo sendo interpretado, os programas em Java precisam ser compilados. Um desenvolvedor de aplicações Java trabalhará com o Kit de Desenvolvimento Java (JDK), sendo que neste estará presente o compilador Java.
O processo de compilação é realizado pelo comando

javac

Por exemplo, seguindo a orientação da figura acima, para compilarmos o arquivo Exemplo.java faríamos:

javac Exemplo.java

Tendo como suposição que não ocorra nenhum erro de compilação (ou seja, não há erro de sintaxe no código fonte), esse processo vai gerar o programa Java. É natural pensarmos que o produto da compilação seja o executável. No Java a ideia de executável não existe. Lembre-se que um programa Java é interpretado.
Continuando: como resultado da compilação, teremos o arquivo Exemplo.class. Esse arquivo é chamado, pelas definições na linguagem Java, de bytecode.
A JVM é capaz de interpretar esse bytecode e “pedir” ao SO (e hardware) as ações necessárias para execução das rotinas. Num ambiente típico a “execução” desse bytecode Exemplo.class ocorreria com o comando:

java Exemplo

Note que o bytecode foi gerado com a extensão .class, porém quando este for executado, vamos omitir o .class

Sopa de letrinhas
Ainda pensando em Java, nos deparamos com várias siglas misteriosas. Vamos indicar o significado de algumas.

J2SE (Java 2 Standard Edition) - quando se fala em Java SE, agrupamos todo o tipo de desenvolvimento e API de programação para aplicações desktop (ou cliente-servidor) comuns. Ou seja, Janelas gráficas, manutenção de arquivos, Sockets de Rede, acesso à Banco de Dados, XML, Threads, etc, são os itens explorados nesse tipo de aplicações. Geralmente cursos em Java começam introduzindo conceitos iniciais do Java SE. Faremos aqui percurso similar.

J2EE (Java 2 Enterprise Edition) - aplicações corporativas, disponibilizadas em páginas web, web services, componentes (sem entrar no mérito ainda, mas por componentes, leia-se EJB) disponíveis na rede, etc, são o foco de trabalho dessa esfera do Java. Além da API sofisticada, especificações dos containers (servidores onde as aplicações EE rodam) também fazem parte da J2EE.

J2ME (Java 2 Micro Edition) - o Java oferece uma plataforma específica para dispositivos móveis. Esses dispositivos, por terem hardware limitado (fato que hoje, nem sempre é verdade), serão atendidos por uma JRE otimizada - ou seja, que consome menos recursos do sistema para rodar aplicações Java. Então quando se fala em Java ME, nosso foco são aplicações para celulares, PDAs e afins.

JRE (Java Runtime Environment) - esse é o cara! O runtime do Java, capaz de interpretar os bytecodes, está contida na JRE. Isso significa que caso você queira executar alguma aplicação Java no seu computador, você precisará instalar o JRE. Como você, provavelmente já executou algum programa em Java (mesmo sem saber), já deve existir uma JRE na sua máquina.

JDK (Java Development Kit) - esse será nosso parceiro neste estudo. O Kit de Desenvolvimento Java, além de conter uma JRE, oferece uma gama de recursos usados no dia a dia do desenvolvimento de aplicações. Itens como o compilador, gerador de documentação, visualizador de applets, etc, estão disponíveis nesse pacote.

O que devo fazer agora?
Bom, falaremos mais sobre isso na segunda aula, mas caso você queira baixar seu JDK (SE), entre no site da Oracle. O download é gratuito: http://www.oracle.com/technetwork/java/javase/downloads/index.html

Afinal, o Java é da Sun o da Oracle?
O Java foi concebido pela Sun, que por sua vez foi comprada pela Oracle. Conclusão: acho que a Oracle quer dominar o mundo... mas esse papo fica pra outra ocasião.

Orientação a Objetos
Quando se fala em Java, se fala em Orientacão a Objetos. Mas afinal, o que é um objeto?
A ideia da programação orientada a objetos é tentar obter do mundo real, características e comportamentos inerentes aos objetos. Isso significa que quando se trabalha com objetos, não pensamos mais em dados soltos na aplicação e procedimentos que realizam as regras de negócio. Pensamos agora em elementos independentes, porém cooperativos para atingir um objetivo.
Grosseiramente falando, ao invés de você programar um tripão de código que sai chamando procedures para manipular dados de todos os tipos, agora você agrupa as procedures e dados em elementos menores, que trocam informações e serviços entre si. Esses elementos menores são os nossos objetos.

Tudo fica mais fácil na vida quando se coloca na prática. Vamos imaginar, por exemplo, um carro. Quais são as características de um carro no mundo real? cor, velocidade máxima, cavalos, litros do porta-malas, preço, tipo de combustível (gasolina, álcool, total-flex), fabricante, modelo, entre muitas outras. Podemos então entender que um objeto carro contém todos esses atributos.
Além disso, o que um carro realiza? Ou seja, quais são os comportamentos de um carro?
Um carro “liga o motor”, “aumenta a velociadade”, “diminui a velocidade”, “troca de marcha”, “fura o pneu”, etc.
Perceba que um carro pode conter infinitos comportamentos.
Esse seria o objeto carro do mundo real. Como faremos então para transportá-lo para o computador?
Falaremos agora da abstração.

Os 4 pilares da Orientacão a Objetos - Abstração
Ao longo do curso falaremos de quatro entedimentos básicos para aqueles que desejam trabalhar com orientação a objetos. Um deles é a Abstração. A Abstração é um prisma a partir do qual devemos considerar, dentre todos os atributos de comportamentos de um objeto do mundo real, apenas aqueles que forem de importância explícita para o sistema computacional. Ou seja, imagine-se modelando um sistema de seguro para automóveis. Seria necessário você armazenar e tratar o tamanho do porta-malas do carro? Acredito que não. Todavia, essa informação talvez já seja importante para um sistema de delivery, onde os carros, na verdade, teriam compartimentos de carga grandes, médios ou pequenos.
Pensando ainda além, se estivéssemos desenvolvendo um jogo de corrida de carros? Talvez pudéssemos enxergar detalhes como velocidade, quantidade de gasolina atual, capacidade do tanque de gasolina, velocidade máxima, etc.
Percebam que a partir de um mesmo objeto do mundo real nós conseguimos abstrair diversas particularidades que variaram acordando com o sistema planejado. De forma semelhante, a definição de um comportamento “acelerar” pode ser importante para um sistema. Para outro, talvez um comportamento “registrar locação de carro”.

Esse tipo de idealização dos comportamentos e atributos do mundo real sob a ótica de necessidade do sistema é dito como Abstração. Só para matar a curiosidade, os outros três pilares são: herança, encapsulamento e polimorfismo. Falaremos deles no futuro.

Exemplo de Orientação a Objetos
Ainda mantendo o exercício do carro, vamos imaginar um jogo de corrida - a priori, bem básico, onde um carro apenas aumenta e diminui a velocidade.
Tendo como base os comportamentos de “aceleração” e “frenagem”, podemos inferir que será necessário trabalhar com um atributo Velocidade Atual e outro Velovidade Máxima (que seria o limite superior da Velocidade Atual). Dessa forma, chegamos a uma possível representação desse objeto conforme mostrado abaixo:


Que caixa é essa?
Lembra que cheguei a comentar que eventualmente usaríamos notações UML para trabalhar com orientação a objetos? Pois é. Essa caixa pertence ao Diagrama de Classes e é dita uma Classe. Num resumão, podemos compreendê-la da seguinta forma:


Então, como discutimos, nosso objeto Carro terá os atributos “velocidade atual” e “velocidade máxima”, que identificamos como sendo ambos do tipo inteiro (vide a sintaxe int ao lado dos atributos). Terá também dois comportamentos: acelerar() e frear(). Observe também que, por conveniência da explicação que faremos mais a frente, um dos métodos possui o indicativo void para sinalizar que não há retorno e o outro int para indicar que após sua execução, ele retornará um valor inteiro.

Mas espera ai!? Você disse que isso é uma Classe! Cadê o Objeto?
Já que você tocou no assunto, vamos à explicação: Uma Classe é um esqueleto que define como nosso Objeto será. Imagine como sendo a planta de uma casa (esse exemplo já é muito manjado, mas é bem simples). A casa em si, depois de pronta seria um objeto que foi construido a partir de uma planta. Nesse cenário, a planta seria a Classe e a casa seria o Objeto.
No vocabulario “javeiro” atual, quando criamos um objeto a partir de uma classe, podemos dizer que estamos instanciando o objeto - ou seja, gerando algo tangível, do ponto de vista de software, alocando memória principal para armazenar os dados pertinentes àquele objeto.
Então, na verdade nós pensamos nas classes a partir das quais serão gerados o objetos. A caixinha mostrada acima exibe exatamente uma Classe Carro de onde poderemos no futuro instanciar nossos objetos do tipo Carro.

E o Java, aonda está?
Veja abaixo o exemplo de código Java para implementar essa classe:

class Carro {
  int velocidadeAtual;
  int velocidadeMax;
 
  int acelerar() {
    if ( velocidadeAtual <= velocidadeMax )
      velocidadeAtual = velocidadeAtual + 1;
    return velocidadeAtual;
  }
  void frear() {
    if ( velocidadeAtual > 0 )
      velocidadeAtual = velocidadeAtual - 1;
  }
}

Veja que o código apresenta lógicas de comportamento simples para os métodos. Não faz sentido, por exemplo, que a velociadeAtual do carro seja inferior a zero. Portanto, quando se usa o método frear(), espera-se que o limite zero seja respeitado. De forma semelhante, o carro só poderá aumentar a velocidade quando ainda não tiver alcançado o limite superior velocidadeMax.

Observações a respeito do código
Veja que na UML especificamos o tipo de um atributo após a definição do nome do atributo (por exemplo, velocidadeAtual : int). No Java, todavia, a definição é tipo do atributo + nome do atributo.
No caso dos métodos, observamos as mesmas características, sendo que no Java, quando um método estabelece um valor de retorno qualquer (no caso do acelerar(), o tipo int), devemos obrigatoriamente, no código do corpo do método, declarar a sintaxe return retornando uma variável (ou valor fixo) equivalente ao tipo de retorno identificado - podemos retornar o atributo velocidadeAtual pelo fato deste ser int, igual ao valor de retorno definido no método em questão.

Chegamos assim ao fim do conteúdo da primeira aula. No próximo material daremos uma exemplo de como manipular a classe Carro do ponto de vista do código e do tratamento dos objetos pela JVM.

Agradeço pela leitura.
Abraços, Guilherme Pontes

Nenhum comentário:

Postar um comentário