Java Parte I mleal@inf.puc-rio.br 1 Introdução LP OO desenvolvida pela Sun no início da década de 90 com sintaxe semelhente a C\C++. C C++. Todos os programas Java são compilados e interpretados. O compilador transforma o programa em um forma intermediária independente da plataforma (bytecodes). O interpretador (JVM) testa e executa os bytecodes. mleal@inf.puc-rio.br 2
Introdução Para cada plataforma é necessário uma JVM específica. Entretanto, um mesmo programa pode ser executado em qualquer plataforma. mleal@inf.puc-rio.br 3 Classes em Java Em Java, a declaração de novas classes é feita através da construção class. class Circulo { int x,y; float raio; mleal@inf.puc-rio.br 4
Instanciação Uma vez definida uma classe, uma nova instância (objeto) pode ser criada através do comando new. Circulo c = new Circulo(); Os atributos desta classe podem ser manipulados diretamente: c.x = 5; c.y = 5; c.raio = 3.5; mleal@inf.puc-rio.br 5 Métodos Além de atributos, uma classe deve declarar os métodos que irá disponibilizar. class Circulo { int x,y; float raio; void setraio(float r){ raio = r; float getarea(){ return 3,14*raio*raio; void move (int dx, int dy){ x = x+dx; y = y+dy; mleal@inf.puc-rio.br 6
Declaração de Variáveis e Escopo Java permite que uma variável seja declarada em qualquer lugar dentro de um método. O escopo da variável se estende do momento da sua declaração até o fim do bloco no qual foi definido. int fatorial (int n){ if n <= 1 then return 1 else { int f = n*fatorial(n-1) return f escopo de f mleal@inf.puc-rio.br 7 Envio de Mensagens O envio de uma mensagem para um objeto é feito através da invocação de métodos deste objeto com a eventual passagem de parâmetros. Circulo c = new Circulo(); c.setraio(3); float a = c.getarea(); mleal@inf.puc-rio.br 8
Referências Java adota um modelo de valor por referência. Com exceção de tipos primitivos, a atribuição entre duas variáveis cria uma nova referência Circulo c1 = new Circulo(); Circulo c2 = c1; c1 e c2 contém m referências para o mesmo objeto Circulo mleal@inf.puc-rio.br 9 this Dentro de um método, o objeto pode precisar de sua própria referência. A palavra reservada this denota uma referência ao próprio objeto. class Circulo { int x,y; void setxy (int x, int y){ this.x = x; this.y = x; mleal@inf.puc-rio.br 10
Inicialização de Objetos Em várias circunstâncias é interessante inicializar um objeto com valores. Por exemplo, poderíamos querer que todo Círculo recém criado estivesse em (0,0). Esse tipo de inicialização pode ser feito especificando-se se valores iniciais para os atributos: class Circulo { int x = 0; int y = 0; mleal@inf.puc-rio.br 11 Construtores Ao invés de criar pontos sempre em (0,0), poderíamos querer especificar a posição do ponto no momento de sua criação. O uso de construtores permite isso. Construtores são mais genéricos do que simples atribuições de valores iniciais aos campos: podem receber parâmetros e fazer um processamento qualquer. mleal@inf.puc-rio.br 12
Exemplo class Circulo { int x,y; float raio; Circulo (int x, int y, float Raio){ Circulo c1 = new Circulo(3,3,5.5); Circulo c2 = new Circulo(0,0,4); Neste exemplo para criar um Circulo é sempre necessário especificar sua posição e o seu raio. mleal@inf.puc-rio.br 13 Construtor Padrão Quando não especificamos nenhum construtor a linguagem Java declara implicitamente um construtor padrão vazio, que não recebe parâmetros. Se declararmos algum construtor, esse construtor padrão não será mais declarado. No exemplo anterior: Circulo c3 = new Circulo(); erro!! mleal@inf.puc-rio.br 14
Sobrecarga Java permite a sobrecarga de métodos, inclusive de construtores. class Point { int x, y; Point() { this(0,0); Point(int x, int y) { this.x = x; this.y = y; mleal@inf.puc-rio.br 15 Gerência de Memória Java possui uma gerência automática de memória com coleta de lixo. Quando um objeto não é mais referenciado pelo programa ele é automaticamente coletado (destruído) e a memória correspondente é desalocada. Qualquer objeto Java é criado sempre na heap. Apenas tipos primitivos são alocados na pilha ou, eventualmente, na memória estática. mleal@inf.puc-rio.br 16
Destrutores Quando um objeto Java vai ser coletado, ele tem seu método finalize chamado. Esse método deve efetuar qualquer procedimento de finalização que seja necessário antes da coleta do objeto. Como Java possui gerenciamento automático de memória, a utilização de destrutores não é muito comum. mleal@inf.puc-rio.br 17 Encapsulamento A definição da interface de objetos é feita através dos modificadores public e private. Métodos e atributos declarados como public são visíveis para outros objetos Java. Métodos e atributos declarados como private só podem ser acessados dentro do próprio objeto. mleal@inf.puc-rio.br 18
Exemplo interface class Circulo { private int x,y; não são acessíveis por private float raio; outros objetos public void setraio(float r){ raio = r; public float getarea(){ return 3,14*raio*raio; public void move (int dx, int dy){ x = x+dx; y = y+dy; mleal@inf.puc-rio.br 19 Atributos de Classes e Métodos Estáticos Classes podem declarar membros (atributos e métodos) que sejam comuns a todas as instâncias, ou seja, membros compartilhados por todos os objetos da classe. Este mecanismo equivale a definição de variáveis e funções globais comuns em LPs não OO. Java suporta a definição de membros de classe através do qualificador static. mleal@inf.puc-rio.br 20
Exemplo public class Math{ static double pi = 3.14; static double cos(){ public class Produto{ static int produzidos = 0; static float getproducao(){ return produzidos; public Produto(){ ++produzidos; mleal@inf.puc-rio.br 21 Acesso a Membros de Classe Não é necessário que uma instância da classe exista pra que membros (atributos e métodos) da classe possam ser acessados. O acesso a membros de classe em Java é feito diretamente através do nome da classe. float perimetro = 2*Math.pi*r; float x = Math.cos(2.3); int n = Produto.getProducao(); mleal@inf.puc-rio.br 22
Tipos Básicos de Java boolean char byte short int long float double true ou false caracter UNICODE (16 bits) número inteiro com sinal (8 bits) número inteiro com sinal (16 bits) número inteiro com sinal (32 bits) número inteiro com sinal (64 bits) número em ponto-flutuante (32 bits) número em ponto-flutuante (64 bits) mleal@inf.puc-rio.br 23 Strings e Arrays Em Java strings e arrays são definidos através de classes específicas. Exemplos: String texto = Exemplo ; int[] lista = {1, 2, 3, 4, 5; String[] nomes = { João, Maria ; System.out..out.println(nomes[0]); // Imprime João. mleal@inf.puc-rio.br 24
Operadores Operadores Aritméticos Descrição Operador Adição + Subtração - Multiplicação * Divisão / Resto divisão inteiro % Menos unário - mleal@inf.puc-rio.br 25 Operadores Operadores Relacionais Descrição Operador Igual == Diferente!= Menor < Menor ou igual <= Maior > Maior ou Igual >= Operadores lógicos and (&&( &&), or ( ( ) ) e not (!)( mleal@inf.puc-rio.br 26
if-else Controle de Fluxo switch-case case-default while do-while for break return mleal@inf.puc-rio.br 27 if-else float m; if (a>0 && b>0) m = a*b; else { System.out.println( Erro ); m = 0; mleal@inf.puc-rio.br 28
switch-case case-default int i = f(); switch (i){ case -1: break; case 0: break; default: mleal@inf.puc-rio.br 29 int i = 0; while (i<10){ i++; while System.out..out.println(i); mleal@inf.puc-rio.br 30
do-while int i = 0; do{ i++; System.out..out.println(i); while (i<10); mleal@inf.puc-rio.br 31 for for (int( i=1; i<=10; i++) System.out..out.println(i); mleal@inf.puc-rio.br 32
break int i = 0; while (true){ if (i==10) break; i++; System.out..out.println(i); mleal@inf.puc-rio.br 33 label início: for (int( i=0; i<10; i++) for (int( j=0; j<10; j++) { if (v[i][j] < 0) break início; mleal@inf.puc-rio.br 34
Herança em Java Java suporta o conceito de herança simples, mas não o de herança múltipla na forma tradicional. Pode-se declarar uma subclasse através da palavra reservada extends: public class Pixel extends Point { int color; public Pixel(int x, int y, int c) { super(x, y); color = c; mleal@inf.puc-rio.br 35 super Uma subclasse pode acessar o construtor da superclasse através da chamada super(). Caso a subclasse não invoque explicitamente o construtor da superclasse, Java fará isso automaticamente. Entretanto caso a superclasse não possua um construtor padrão, a subclasse necessariamente deverá fazer uma invocação explícita de um construtor qualquer da superclasse. mleal@inf.puc-rio.br 36
Polimorfismo Em Java o comportamento padrão dos objetos é polimórfico, e a ligação de métodos ocorre de forma dinâmica (late binding). Conforme veremos adiante, é possível modificar este comportamento quando necessário. mleal@inf.puc-rio.br 37 public class Point { public void print() { System.out.println( Point ( +x+, +y+ ) ); public class Pixel extends Point { public void print() { System.out.println( Pixel ( +x+, +y+, +color+ ) ); Point pt = new Point(); // ponto em (0,0) Point px = new Pixel(0,0,0); // pixel em (0,0) pt.print(); // Imprime: Point (0,0) px.print(); // Imprime: Pixel (0,0,0) mleal@inf.puc-rio.br 38
Valores Constantes Constantes em Java são declaradas através da palavra reservada final. final força uma ligação estática entre um valor e uma variável. class Math { final float pi = 3.14; mleal@inf.puc-rio.br 39 final e Polimorfismo Por razões de eficiência, Java permite a especificação de métodos cuja ligação deve ser sempre estática. Esta especificação é feita através da declaração de um método como final. public class A { public final int f() { mleal@inf.puc-rio.br 40
Type Casting O mecanismo de typecasting é importante em LPs OO para acessar os métodos específicos de objetos polimórficos: Point pt = new Pixel(0,0,1); Pixel px = (Pixel)pt; pt = new Point(); px = (Pixel)pt; ERRO! pt agora contém um ponto. pt = new Pixel(0,0,0); px = pt; ERRO! pt não é sempre um pixel. mleal@inf.puc-rio.br 41 instanceof Permite verificar em tempo de execução a classe real de um objeto. Exemplo: if (pt instanceof Pixel) { Pixel px = (Pixel)pt; mleal@inf.puc-rio.br 42
Classes Abstratas Java suporta o conceito de métodos e classes abstratas através da palavra reservada abstract. Uma classe pode ser declarada abstrata sem conter nenhum método abstrato. Uma classe que contenha ao menos um método abstrato deve sempre ser declarada abstrata. mleal@inf.puc-rio.br 43 Exemplo de Classe Abstrata public abstract class Instrumento { public String nome; public abstract void tocar(); public abstract void afinar(int ajuste); public void getnome() { System.out.println(nome); mleal@inf.puc-rio.br 44
Interfaces Java não suporta o mecanismo de herança múltipla. Uma subclasse pode estender apenas uma única superclasse. Entretanto Java permite que uma subclasse implemente várias interfaces. Interfaces Java podem ser entendidas como classes abstratas puras, ou seja, classes que contém apenas métodos abstratos. Para herdar de uma interface uma subclasse deve ser declarada com a paravra reservada implements. mleal@inf.puc-rio.br 45 Membros de Interfaces Uma vez que uma interface não possui implementação, devemos notar que: seus campos devem ser públicos, estáticos e constantes; seus métodos devem ser públicos e abstratos. Como esses qualificadores são fixos, não precisamos declará-los. los. mleal@inf.puc-rio.br 46
Exemplo interface Instrumento { String marca = Yamaha ; static e final void tocar(); abstract e public void afinar(int ajuste); class Tambor implements Instrumento{ void tocar(){ void afinar(int ajuste){ mleal@inf.puc-rio.br 47 Interfaces Apesar de uma interface não ser uma classe, podemos declarar variáveis como sendo de um tipo de interface específico. Instrumento i = new Tambor(); A partir daí aplicam-se todas as regras de polimorfismo e o mecanismo de typecast padrão. mleal@inf.puc-rio.br 48
Interfaces Uma classe pode concomitantemente estender uma subclasse e implementar diversas interfaces, de forma análoga ao mecanismo de herança múltipla. Exemplo: public class SuperHomen extends SuperHeroi implements Voador, VisaoRaioX, SuperForca { mleal@inf.puc-rio.br 49 Programas Java A estrutura de um programa Java consiste exclusivamente na especificação de classes. A execução de um programa em Java consiste na execução de uma classe. Executar uma classe significa executar seu método estático main. O método main deve portanto especificar o programa a ser executado. mleal@inf.puc-rio.br 50
Olá Mundo! class Mundo { public static void main(string[] args) ) { System.out..out.println( Olá Mundo! ); mleal@inf.puc-rio.br 51 Programas Java Um programa em Java usualmente é composto por várias classes. A unidade de compilação em Java é a classe. Cada classe deve ser declarada em um arquivo separado tendo como nome o nome da classe declarada mais a extensão.java. Por exemplo, o arquivo Tambor.java deve conter a definição da classe Tambor. mleal@inf.puc-rio.br 52
Pacotes Para organizar as classes e facilitar a modularidade de código, Java suporta o uso de pacotes. Um pacote é um conjunto de classes e outros pacotes. Pacotes permitem a criação de espaços de nomes, além de mecanismos de controle de acesso. mleal@inf.puc-rio.br 53 Pacotes O nome do pacote qualifica os nomes de todas as classes e outros pacotes que o compõem, criando portanto um espaço de nomes independente. Se todos as classes declarando instrumentos fossem agrupados no pacote instrumentos, poderíamos acessar a classe Tambor através de uma declaração como: instrumentos.tambor t = new instrumentos.tambor(); mleal@inf.puc-rio.br 54
Pacotes Pacotes são tipicamente implementados como diretórios e os arquivos das classes pertencentes ao pacote devem ficar em seu diretório. Hierarquias de pacotes são construídas através de hierarquias de diretórios. Por exemplo o pacote java.tools.instrumentos deve estar localizado numa hierarquia de diretórios com a forma \java\tools\instrumentos. mleal@inf.puc-rio.br 55 Pacotes Para declararmos uma classe como pertencente a um pacote devemos: Declará-la em um arquivo dentro do diretório que representa o pacote; Declarar, na primeira linha do arquivo, que a classe pertence ao pacote, utilizando para isso a palavra reservada package. mleal@inf.puc-rio.br 56
Exemplo package instrumentos; class Tambor implements Instrumento{ void tocar(){ void afinar(int ajuste){ mleal@inf.puc-rio.br 57 Encapsulamento Revisitado Quando não declaramos explicitamente a visibilidade dos membros de uma classe, Java assume que a visibilidade é do tipo friendly. Membros friendly funcionam como public para classes dentro de um pacote e como private para classes fora do pacote. Java disponibiliza ainda o modificador protected,, que permite a visibilidade de membros de uma classe apenas em subclasses desta classe. mleal@inf.puc-rio.br 58
Visibilidade de Classes Todas as classes de um pacote enxergam as demais classes do mesmo pacote. Classes de outros pacotes só são visíveis em uma classe se forem explicitamente importadas através da declaração import. mleal@inf.puc-rio.br 59 Exemplo package instrumentos; import Java.util.ArrayList; import meupacote.*; class Tambor implements Instrumento{ void tocar(){ void afinar(int ajuste){ importa a classe ArrayList do pacote java.util importa todas as classes do pacote meupacote mleal@inf.puc-rio.br 60
Visibilidade É possível declarar uma classe como privada, usando o modificador private. Neste caso a classe deve ser declarada no mesmo arquivo da classe principal que irá utilizar esta classe. O nome do arquivo é o mesmo da classe principal. Quando uma classe for declarada sem um modificador ela será considerada friendly. mleal@inf.puc-rio.br 61 Exceções Java possui dois tipos de exceções: Checked Exceptions - são exceções que devem ser usadas para modelar falhas contornáveis. Devem sempre ser declaradas pelos métodos que as lançam e precisam ser tratadas (a menos que explicitamente passadas adiante). Unchecked Exceptions - são exceções que devem ser usadas para modelar falhas incontornáveis. Não precisam ser declaradas e nem tratadas. mleal@inf.puc-rio.br 62
Exceções O tratamento de exceções é feito através de estruturas de controle delimitadas pelas palavras reservadas try-catch catch-finally. Todo trecho de código no qual podem ser lançadas exceções do tipo checked deve ser declarado dentro de um bloco try. As rotinas responsáveis pelo tratamento de exceções são declaradas em um bloco catch. mleal@inf.puc-rio.br 63 Exemplo FileReader f = null; try { f = new FileReader(args[0]); f.close(); abre um arquivo - pode lançar uma exceção do catch (IOException e){ tipo IO System.out.println(e); if (f!= null) f.close(); captura a exceção mleal@inf.puc-rio.br 64
Exceções Um bloco try pode conter vários tratadores de exceção. O bloco finally permite especificar um trecho de código que sempre deve ser executado independentemente da ocorrência de exceções. Se uma exceção não for tratada pelo bloco que a lançou, ela irá se propagar seguindo a pilha de chamadas (cadeia dinâmica). mleal@inf.puc-rio.br 65 Exemplo FileReader f = null; try { f = new FileReader(args[0]); catch (IOException e){ System.out.println(e); catch (OutraException e){ System.out.println(e); finally{ if (f!= null) f.close(); sempre executa mleal@inf.puc-rio.br 66
Exemplo FileReader f = null; try { f = new FileReader(args[0]); catch (IOException e){ System.out.println(e); catch (OutraException e){ System.out.println(e); finally{ if (f!= null) f.close(); sempre executa mleal@inf.puc-rio.br 67 Exceções Pode-se ainda definir novas exceções através da especialização da classe Exception ou de qualquer uma de suas subclasses. Métodos que não tratam uma exceção do tipo checked devem declarar isso explicitamente em sua assinatura através do modificador throws. mleal@inf.puc-rio.br 68
Exemplo public void metodox() throws IOException{ FileReader f = null; try { f = new FileReader(args[0]); indica o possível lançamento f.close(); desta exceção catch (Exception e){ System.out.println(e); if (f!= null) f.close(); trow e; captura qualquer exceção relança a exceção mleal@inf.puc-rio.br 69