UERN – Ciência da Computação Programação Orientada a Objetos Prof. André Gustavo [email protected] Programação Orientada a Objetos Ementa ◦ Paradigma da Programação Orientada a Objetos Classes e Objetos Encapsulamento Herança Polimorfismo ◦ Interface gráfica ◦ Eventos ◦ Tratamento de erros. Programação Orientada a Objetos Livro Texto ◦ Core Java 2 - Vol. 1: Fundamentos - Cay S Horstmann Livros de Referência ◦ Introdução à Programação Orientada a Objetos Usando Java - Rafael Santos ◦ Java Como Programar - 6ª Edição Harvey M. Deitel, Paul J. Deitel Programação Orientada a Objetos Software de Apoio (grátis) ◦ Compilador Java (http://www.oracle.com/technetwork/java/j avase/downloads/index.html) ◦ Ambiente de desenvolvimento (JCreator, Eclipse, Netbeans, etc.) Programação Orientada a Objetos POO x PE ◦ A Prog. Estruturada prioriza os algoritmos ◦ A Prog. Orientada a Objetos prioriza a definição das estruturas de dados (objetos) Objetos ◦ Componentes de software reutilizáveis que modelam itens do mundo real. ◦ Possuem atributos (dados) e comportamentos (métodos). Programação Orientada a Objetos Classes ◦ Descrição de um grupo de objetos, cada um deles em um estado específico, mas capazes de executar as mesmas operações. ◦ É a base da modularidade de um programa, podendo dividi-lo em partes menores e mais gerenciáveis ◦ A partir das classes os objetos são criados (instanciados) Programação Orientada a Objetos Principais Linguagens: ◦ C++ Linguagem híbrida (programação estruturada e/ou orientada a objetos) ◦ C# ◦ Java Java ◦ Mascote oficial: Duke Java Java ◦ Nome da cidade de origem de um tipo de café ◦ Lançamento em 1995 ◦ Linguagem orientada a objetos “pura” ◦ Criada pela Sun Microsystems em 1990 ◦ A Sun foi adquirida pela Oracle em 2009 ◦ Inicialmente desenvolvida para ser utilizada em dispositivos eletrônicos como eletrodomésticos e automóveis. ◦ Sintaxe muito parecida com C++ Java Java Vantagens: ◦ ◦ ◦ ◦ ◦ ◦ Grátis Portabilidade Segurança Coleta de lixo automática Maior simplicidade do código Suporte Java Community Process (JCP) é mantido por diversas empresas: Oracle, IBM, Novell, Xerox, dentre outras. Tornou-se software livre através do projeto OpenJDK Amplo mercado de trabalho Java James Gosling – Pai do Java ◦ Deixou a Oracle em 2010 Java Possui três versões principais, de acordo com o hardware e o tipo de aplicação utilizado: ◦ J2ME (Java 2 Micro Edition) ◦ J2SE (Standard Edition) ◦ J2EE (Entreprise Edition) Java API – Aplication Programming Interface (http://www.oracle.com/technetwork/java/java se/documentation/api-jsp-136079.html) Criado o Ginga-J, que permite Java na TV Digital Brasileira Java É uma linguagem compilada e interpretada: ◦ Compilada: gera um código intermediário, chamado arquivo bytecode (com extensão .class), que é independente da plataforma. ◦ Interpretada: Os bytecodes são então interpretados pela máquina vitual Java, esta sim dependente da plataforma. Esse fator prejudica a performance dos programas Java Tarefa Ferramente Utilizada Saída Escrever o programa Qualquer editor de texto Compilar o Programa Compilador Java Executar o programa JVM Arquivo com extensão .java Arquivo com extensão .class Saída do Programa Java x Estruturas em C // Programa em C #include <stdlib.h> struct cadastro{ int codigo; char nome[80]; float salario; }; main(){ struct cadastro func; func.codigo = 1; strcpy(func.nome,"Maria"); func.salario = 345.34; printf(“%d - %s %f”,func.codigo, func.nome, func.salario); } // Classe Java class Cadastro{ int codigo; String nome; double salario; } public class Exemplo { public static void main(String args[ ]) { Cadastro x; x = new Cadastro(); x.codigo =1; x.nome = “Maria"; x.salario=345.34; System.out.println(x.nome + x.codigo + x.salario); } } Java Ao instanciar um objeto, seu endereço é armazenado em um atributo. Ex: Pessoa X; X = new Pessoa (“Maria”, 25,1.65); Descrição Valor Variável X do tipo classe Pessoa 1549 (ponteiro) ... Endereço 1000 Objeto do tipo classe Pessoa Campo Nome: Maria Campo Idade: 25 Campo Altura: 1.65 1549 Java Não é possível acessar campos pelo endereço da memória, aumentando assim a segurança do código. O arquivo java deverá possuir o mesmo nome da classe pública contida no mesmo. Assim, um arquivo pode possuir várias classes, porém somente uma pública. class Cadastro{ private int codigo; private String nome; private double salario; public void setCodigo(int c){ codigo = c; } public void setNome(String n){ nome = n; } public void setSalario(double s){ if(s > 0) salario = s; } public int getCodigo(){ return codigo; } public String getNome(){ return nome; } public double getSalario(){ return salario; } } public class Ex01{ public static void main(String args[ ]){ Cadastro x; x = new Cadastro(); x.setCodigo(1); x.setNome("Maria"); x.setSalario(345.34); System.out.println(x.getNome() + x.getCodigo() + x.getSalario()); } } Atributos Um atributo pode ser acessível ou não em outra classe, dependendo do seu escopo: Escopo Classe Pacote Subclasse Mundo private S N N N no specifier S S N N protected S S S N public S S S S O tipo do atributo pode ser primitivo ou outra classe. Atributos Os tipos primitivos de dados utilizados são: ◦ Tipo inteiro: int (4 bytes), long(8 bytes), short(2 bytes) , byte(1 byte ) ◦ Tipo real: double (8 bytes ), float (4 bytes) ◦ Tipo lógico: Boolean (1 byte) ◦ Tipo caracter: Char (2 bytes ) Métodos Sintaxe: <modificador de acesso> <tipo de valor de retorno> <nome do método> ( argumentos) ◦ Modificador de acesso (escopo): protected, private, public, sem identificador ◦ Tipo de valor retornado: classe (por referência), tipo primitivo de dados (por valor), void (sem retorno) ◦ Argumentos: lista de argumentos separados por vírgula, sendo necessário especificar o tipo e um identificador para cada parâmetro ◦ Os argumentos de um método também são variáveis locais ◦ Podem retornar nenhum ou um único valor. Métodos Os métodos mais comuns são os acessadores e modificadores. A combinação formado pelo nome do método mais o conjunto de parâmetros(tipo, quantidade e ordem) é chamado de assinatura. É permitido criar vários métodos com o mesmo nome, desde que tenham assinaturas diferentes; esse recurso é chamado de sobrecarga de método. São permitidos métodos recursivos Encapsulamento Forma de restringir o acesso de atributos e métodos a membros de uma classe através da palavra-chave private. Oculta detalhes da implementação da classe Torna mais fácil qualquer futura modificação no código. O programador da classe controla como os dados (atributos) serão manipulados Você instancia os objetos sabendo o que eles fazem, mas não precisa saber como o fazem Ex02: Chamada de métodos public class Ex02{ class Funcionario{ public static void main(String a[ ]){ private int idade; private String nome; private double salario; Funcionario x; x = new Funcionario(); x.setIdade(17); x.setNome("Maria"); x.setSalario(345.34); System.out.println( x.getNome() + " - " + x.getIdade() + " - " + x.getSalario() ); public void setIdade(int i){ idade = i; } public void setNome(String n){ nome = n; } public void setSalario(double s){ if(s >=0) salario = s; } public int getIdade( ) { return idade; } public String getNome( ){ return nome; } public double getSalario( ){ return salario; } x.setDados( 22, "Chico"); System.out.println( x.getNome() + " - " + x.getIdade() + " - " + x.getSalario() ); x.setDados( 27, "Joao", 360.1); System.out.println( x.getNome() + " - " + x.getIdade() + " - " + x.getSalario() ); Funcionario y; y = x; y.setNome("Ana"); System.out.println( x.getNome() + " - " + x.getIdade() + " - " + x.getSalario() ); public void setDados( int i, String n){ setIdade(i); setNome(n); setSalario(0); } } public void setDados( int i, String n, double s){ setIdade(i); setNome(n); setSalario(s); } } } Herança Permite criar uma classe, definindo-a em termos de outra classe já existente, em vez de montar a classe a partir do nada. Na prática, é uma maneira de evitar repetição de código. Uma classe recém-criada absorve as características(atributos e métodos) da classe herdada e adiciona características próprias Todas as classes do Java herdam implicitamente a classe Object Se ao imprimir um objeto nenhum dos seus métodos é especificado, o método toString(), herdado da classemãe Object, é executado. Para acessar métodos da classe ancestral explicitamente, utilizamos a cláusula super com o nome do método. class Funcionario{ private int idade; private String nome; private double salario; public void setIdade(int i){ idade = i; } public void setNome(String n){ nome = n; } public void setSalario(double s){ if(s>0) salario = s; } public int getIdade( ){ return idade;} public String getNome( ){ return nome; } public double getSalario( ){ return salario; } public void setDados( int i, String n, double s) { setIdade(i); setSalario(s); setNome(n); } public void aumentaSalario( double p){ salario = salario*(1+(p/100)); } } class Gerente extends Funcionario { private int anosGerencia; public void setAnosGerencia( int a){ if( anosGerencia < a ) anosGerencia = a; } public void aumentaSalario( double p){ double salNovo, salAntigo; salAntigo = getSalario(); salNovo = salAntigo*(1+(p/100)) + anosGerencia*(salAntigo*0.05); // Ou: super.aumentaSalario(p); // salNovo = getSalario() + anosGerencia * setSalario( salNovo); } public String toString(){ return getNome() + getIdade(); } } (salAntigo*0.05); public class Ex03{ public static void main(String a[ ]){ Funcionario x; x = new Funcionario(); x.setDados(17, "Maria", 360.1); Gerente z = new Gerente(); z.setDados(41,"Marco",360.1); z.setAnosGerencia(2); z.aumentaSalario(10); x.aumentaSalario(10); imprime(x); imprime(z); System.out.println(x.toString()); System.out.println(z.toString()); System.out.println(z); } public static void imprime (Funcionario x){ System.out.println( x.getNome() + x.getIdade() + x.getSalario() ); } } Construtores Método com o mesmo nome da classe, sendo invocado automaticamente quando se instancia um objeto. Utilizado principalmente para inicializar o conteúdo dos atributos (variáveis de instância) Não podem especificar nenhum tipo de retorno. Podem conter construtores sobrecarregados com diferentes assinaturas Construtores Um construtor que não possui argumentos é chamado de construtor default Se nenhum construtor é definido na classe, o compilador cria um construtor default Para acessar um construtor da superclasse, utilizamos a palavra-chave super junto com os parâmetros, obrigatoriamente como o primeiro comando no construtor. Quando nenhum construtor da classe mãe é chamado explicitamente, o seu construtor padrão é executado, o que significa que, caso este construtor default não exista, haverá erro de compilação. class Funcionario { private String nome ; private int idade; private double salario; public String getNome(){ return nome; } public int getIdade(){ return idade; } public Funcionario(){ setNome("Sem identificação"); setIdade(0); setSalario(0); } public double getSalario(){ return salario; } public void setNome( String n){ nome = n; } public Funcionario( String n ){ setNome(n); setIdade(0); setSalario(0); } public void setIdade(int i ){ if(i < 120 && i>=0) idade = i; } public Funcionario (String n, int i){ setNome(n); setIdade(i); setSalario(0); } public Funcionario( String n, int i, double a){ setNome(n); setIdade(i); setSalario(a); } public void setSalario( double s){ if(s > 0) salario = s; } public String toString(){ return "Nome: " + getNome() + "Idade: " + getIdade() + "; Salário: " + getSalario(); } public void aumentaSalario(double p){ salario= salario*(1+ (p/100)); } } public class ex01{ public static void main( String args[] ){ Funcionario emp1 = new Funcionario(); Funcionario emp2 = new Funcionario("Maria"); Funcionario emp3 = new Funcionario("João",23); Funcionario emp4 = new Funcionario("Francisco", 28,989.23); System.out.println( emp1 ); System.out.println( emp2 ); System.out.println( emp3 ); System.out.println( emp4 ); } } Herança de construtores public int getAnosGerencia(){ class Gerente extends Funcionario { return anosGerencia; } private int anosGerencia ; public String toString() { public Gerente(){ } return super.toString() + " Anos Gerência: " + getAnosGerencia(); } public Gerente( int anos ){ setAnosGerencia( anos); } public void aumentaSalario(double per){ public Gerente( String n, int a ) { double salarioNovo, salarioAntigo; setNome(n); setAnosGerencia( a); } salarioAntigo = getSalario(); public Gerente(String n, int i, double a, int anos ){ super.aumentaSalario(per); salarioNovo = salarioAntigo + anosGerencia*(salarioAntigo*0.05); super(n,i,a); setAnosGerencia(anos); } setSalario( salarioNovo ); } public void setAnosGerencia( int a ){ if ( a >=0 ) anosGerencia = a; } } public class ex02{ public static void main( String args[] ){ Gerente ger1 = new Gerente(); Gerente ger2 = new Gerente(2); Gerente ger3 = new Gerente("Marco", 3); Gerente ger4 = new Gerente("Joana", 41, 2232.23, 2); System.out.println( ger1); System.out.println( ger2); System.out.println( ger3); System.out.println( ger4); } } Polimorfismo Capacidade de um objeto assumir várias formas Conversão implícita de objeto de subclasse para objeto de superclasse: ◦ Fazer referência a um objeto de subclasse com uma referência para superclasse é seguro, porque o objeto de subclasse também é um objeto de sua superclasse. Tal código pode fazer referência apenas aos membros de superclasse. Se esse código fizer referência aos membros que existem apenas na subclasse através da referência para superclasse, o compilador informará um erro de sintaxe. ◦ Para testar se houve essa conversão, utilizamos o operador instanceof. public class ex03{ public static void main( String args[] ){ Funcionario ger1 = new Gerente("Joana",41,2000,2); Gerente ger2 = new Gerente("Marco",40,2500,1); Funcionario func1 = new Funcionario(); // Erro: Gerente x = new Funcionario(); // Erro: ger1.setAnosGerencia(3); ger2.setAnosGerencia(2); ger1.aumentaSalario(10); // 2400.00 imprimeObject(ger1);imprimeObject(ger2); imprimeObject(func1); imprimeFunc(ger1);imprimeFunc(ger2);imprimeFunc(func1); imprimeGerente(ger1);imprimeGerente(ger2); //imprimeFunc(func1); //Erro: Func1 não é um gerente testaGerente(ger1); testaGerente(ger2); testaGerente(func1); } private static void imprimeObject(Object o){ System.out.println( o ); } private static void imprimeFunc(Funcionario f){ System.out.println( f.getNome() ); } private static void imprimeGerente(Gerente g){ System.out.println( g.getAnosGerencia() ); } private static void testaGerente(Funcionario f){ if( f instanceof Gerente){ System.out.println("Eh gerente"); Gerente x = (Gerente) f; x.setAnosGerencia(3); } else System.out.println("Não eh gerente"); } } Atributos e métodos estáticos (static) Os métodos estáticos existem mesmo quando nenhum objeto dessas classe existe – eles estão disponíveis logo que a classe é carregada na memória durante a execução; podem ser acessados através da referência a qualquer objeto dessa classe, ou pelo nome da classe. Um método static não pode chamar um método de instância ou acessar uma variável de instância. Um atributo estático é semelhante a um método do mesmo tipo. Uma única cópia é criada, com seu valor sendo compartilhando por todas as classes. public class TesteEstatico{ public static int instancias=0; private String nome; public TesteEstatico(){ instancias++; } public TesteEstatico(String n){ this(); nome = n; } public static int getInstancias(){ return instancias; } public String getNome(){ return nome; } public static void main(String[ ] args){ System.out.println( TesteEstatico.getInstancias()) ; TesteEstatico s1 = new TesteEstatico(); TesteEstatico s2 = new TesteEstatico(); TesteEstatico s3 = new TesteEstatico("Maria"); TesteEstatico s4 = new TesteEstatico("Chico"); System.out.println(TesteEstatico.instancias); System.out.println(s1.instancias ); System.out.println(TesteEstatico.getInstancias()); System.out.println(s1.getInstancias()); System.out.println(s4.getNome()); int x = Integer.parseInt("4"); double y = Double.parseDouble("23.2"); System.out.println(x+y); } } Variáveis, métodos e classe do tipo final Uma variável do tipo final não pode ter seu conteúdo alterado (constante). Uma variável final também pode ser static e ser sobrescrita em uma subclasse. Um método do tipo final não pode ser sobrescrito por outro método com a mesma assinatura em uma subclasse. Uma classe final não pode ser uma superclasse. Todos os métodos da classe final são implicitamente final. Esse tipo de classe evita que outros programadores criem subclasses que possam contornar restrições de segurança. Referência This Utilizada para fazer referências às variáveis de instância, aos construtores e aos métodos de um objeto. Se uma variável local de um método possui o mesmo nome de uma variável de instância, esta fica “escondida”, sendo necessária a utilização da referência this Quando this está adicionada a um String e não faz referência a nenhum método, o método toString() é chamado implicitamente É possível retornar a referência ao próprio objeto utilizando a referência this. Finalizadores Java realiza coleta de lixo automática da memória para ajudar a devolver a memória para os sistema. Quando não há referências para o objeto, o mesmo é marcado para coleta de lixo. A memória para esse objeto pode ser reivindicada quando o coletor de lixo é executado. Cada classe em Java pode ter um método finalizador que retorna recursos para o sistema. Esse método tem o nome de finalize e é chamado pelo coletor de lixo. Sintaxe: void finalize(){ } Não é garantido que o coletor de lixo seja executado; portanto, você não pode confiar na chamada do método finalize. A classe System possue o método gc que sugere uma chamada ao coletor de lixo (Garbage Collector). public final class Statico{ this.nome = nome; nome = "Jorge"; private static int instancias=0; public static final int CONST=1; private String nome; public Statico(){ instancias++; } public Statico(String n){ this(); nome = n; } public static int getInstancias(){ return instancias; } public final void setNome(String nome){ System.out.println(nome); System.out.println(this.nome); System.out.println("Nome: " + this); } public void finalize(){ instancias--; } public String toString (){ return nome; } public Statico getInstancia(){ return this; } public static void main(String[ ] args){ System.out.println( Statico.getInstancias() ); s1 = new Statico(); System.out.println( s1.getInstancias() ); System.out.println( Statico.CONST ); Statico s1 = new Statico(); Statico s2 = new Statico(); s4.setNome("Joao"); Statico s3 = new Statico("Maria"); Statico s5 = Statico s4 = new s3.getInstancia(); Statico("Chico"); s3.setNome("Jose"); s1=null; System.gc(); System.out.println( s1.getInstancias() ); System.out.println(s3); System.out.println(s5); } } Classe String Representa uma cadeia de caracteres Podem ser instanciadas de várias formas. Ex: ◦ String inst = “uern”; ◦ String inst = new String(“uern”); ◦ char data[ ] = {'u', 'e, 'r','n'}; String str = new String(data); Strings são constantes, ou seja, ao ser manipulada, uma nova string é criada. Ex: ◦ String var1 = “UERN”; ◦ String var2 = var1.substring(1,2); ; //var1 continua // com o mesmo valor, “UERN” ◦ String var3 = “Brasil”.substring(2,3); //retorna “asi” Classe String Quando uma string é criada, o java verifica se já não existe uma cópia exatamente igual, evitando assim a criação de strings idênticas. Em algumas situações essa verificação não é efetuada com sucesso. Assim, nunca devemos comparar duas strings através do operador '==', mas sim através do método “equals” da classe String.Ex: ◦ String var1 = “UERN”; ◦ String var2 = “UERN”; ◦ if var1.equals(var2) System.out.println(“Strings iguais”) Alguns dos principais métodos: length, charAt, equals, equalsIgnoreCase, startsWith, endsWith, compareTo, indexOf, valueOf, toLowerCase, toUpperCase, trim, replace, substring, concat Classe String Qualquer tipo de dado primitivo, ao ser concatenado com uma String, é automaticamente convertido também em String. Ex: ◦ String x = “uern”; ◦ String y = x + 32.2; // y possui o valor “uern32.2”; Quando uma string é concatenada com outro objeto qualquer, o método toString deste é chamado. Ex: ◦ String x = “uern”; ◦ Empregado y = new Empregado(“João”); ◦ System.out.println(x + y) //Imprime “uernJoão”, supondo ◦ // que a classe Empregado possui um método toString que ◦ // retorna o nome do mesmo. Classe String A classe StringBuffer cria strings mutáveis. Ex: ◦ ◦ ◦ StringBuffer x = new StringBuffer("ur"); x.insert(1,"e");// x possui o valor “uer” x.append("n"); // x possui o valor “uern” Pacotes Coleção de classes, utilizadas para organizar a localização. Para adicionarmos uma classe a um pacote, utilizamos a instrução package, que deve ser utilizada no início do código, seguido do nome do pacote que desejamos adicionar a classe. Ex: package Teste; Para utilizar um pacote já existente, usamos a instrução import seguida do nome do pacote; podemos também importar apenas uma classe do pacote. Ex: import java.util.* ; (importa todas as classes do pacote java.util). Nesse caso, a classe que importa todo o pacote deve obrigatoriamente pertencer a outro pacote que não seja o default. Ex: import Java.util.Date; ( importa apenas a classe date do pacote Java.útil) Só é permitido importar um pacote ou classe para cada instrução import O nome da classe no pacote deve ser único Pacotes O pacote java.lang é importado implicitamente. Se não for especificado nenhum pacote na definição da classe, ela fará parte do pacote padrão (default), que é composto de todas as classes do diretório atual mais as classes contidas nos diretórios informados na variável de ambiente CLASSPATH. Ao importar um pacote, somente as classes do respectivo diretório são acessadas. Classes localizadas em subdiretórios devem ser importadas explicitamente. Ex: import javax.swing.event.*; Não é necessário importar classes que pertencem ao mesmo pacote Pacotes O compilador Java irá procurar pelas classes declaradas no import nos seguintes diretórios, em ordem: ◦ Diretórios incluídos na variável de ambiente CLASSPATH ◦ Diretório atual O modificador de acesso default (sem palavra chave) limita o acesso a classes do mesmo pacote. Ex. class Teste Os membros protected podem ser acessados por métodos da subclasse e por métodos de outra classe no mesmo pacote. A Sun Microsystems especificou uma convenção a ser utilizada ao nomear um pacote: deve-se iniciar com o nome de domínio da empresa na Internet na ordem inversa, seguido do nome do pacote. Ex: br.com.uol.util Para especificar o diretório de localização do pacote durante a compilação, utilize a sintaxe: javac –d <caminho> <classe.java> ; utilize “.” no lugar do caminho para especificar o diretório corrente Pacotes É possível agrupar todas as classes de um pacote em um único arquivo, que possui a extensão ‘jar’. Os principais comandos: 1. gerar jar: jar cf myJar.jar uern (considere uern o pacote a ser agrupado e myJar.jar o arquivo a ser gerado) 2. 3. compilar classe main: javac -classpath myJar.jar teste.java (considere teste.java uma classe que importa o pacote uern) executar classe main: java -classpath .;myJar.jar teste (considere teste uma classe contida na raiz de myJar.jar) Para criar um jar com uma classe principal que será executada, será necessário: ◦ Criar um arquivo txt com a seguinte informação (esse arquivo é chamado pelo java de manifest): Main-Class: MyPackage.MyClass Obs.: O último caracter desse arquivo deverá ser o de nova linha ◦ Gerar o jar: jar cfm MyJar.jar Manifest.txt uern (considere Manifest.txt o arquivo de manifesto) ◦ executar o jar: java -jar MyJar.jar (no windows, duplo clique também executa a classe principal) Classe abstrata e concreta Em uma classe abstrata, não podemos instanciar objetos. Geralmente são utilizadas com uma superclasse com informações genéricas que serão herdadas por outras classes, abstratas ou não. Em uma classe concreta, podemos instanciar objetos. Métodos Abstratos São métodos que devem ser obrigatoriamente sobrescritos pela subclasse, caso a mesma seja uma classe concreta. Uma classe que contém um método abstrato deve ser, obrigatoriamente, abstrata. O método abstrato deve ser declarado apenas com sua assinatura, ou seja, não deve ser implementado. Uma classe abstrata pode conter métodos que não são abstratos abstract class Pessoa{ private String nome; public Pessoa(String n, double s){ setNome(n); setSalario(s); } public void setNome(String n){ nome=n; } public String getNome(){ return nome; } public abstract void aumentaSalario(double s); public abstract void setSalario(double s); public abstract double getSalario(); } class Tecnico extends Pessoa { private String funcao; private double salario; public Tecnico(String n, String f, double s){ super(n,s); setFuncao(f); } public void setFuncao(String f){ funcao = f; } public void setSalario(double s){ salario = s; } public void aumentaSalario(double s){ salario = salario*( 1+ (s/100)); } public double getSalario(){ return salario; } } class Gerente extends Pessoa{ private double anosGerencia; private double salario; public Gerente(String n, double s, double ag){ super(n,s); setAnosGerencia(ag); } public void setAnosGerencia(double ag){ anosGerencia = ag; } public void setSalario(double s){ salario = s; } public void aumentaSalario(double s){ salario=salario*(1+ (anosGerencia*0.05) + (s/100)); } public double getSalario(){ return salario; } } public class PessoaAbs{ public static void main(String args[]){ //Pessoa p1 = new Pessoa("Maria", 120); Tecnico p2 = new Tecnico("Chico","Mecânico",100); Pessoa p3 = new Tecnico("Joao","Serviços Gerais",200); Pessoa p4 = new Gerente("Marcos", 200, 2); p3.aumentaSalario(10); p4.aumentaSalario(10); imprimir(p3); imprimir(p4); } public static void imprimir(Pessoa a){ System.out.println("Nome: " + a.getNome() + " - Salario: " + a.getSalario()); } } Interfaces Tipo de dado que lista os métodos abstratos que devem ser definidos pelas classes concretas que implementarem-na. Possui apenas métodos abstratos e públicos Uma classe pode implementar várias interfaces Não é possível criar instâncias de interfaces Se uma classe implementa uma interface, uma instância dessa classe pode ser passada como argumento para qualquer método que espere com argumento uma referência à interface implementada. Interfaces Se uma classe implementar duas ou mais interfaces que possuem atributos com nome idêntico, essa classe não será compilada. Para saber se uma classe implementa uma interface qualquer, usamos o operador instance of. Os atributos deverão ser static e final, sendo assim útil também para armazenar constantes que serão herdadas pelas classes Se a interface for pública, ela deve ser declarada em um arquivo com o mesmo nome. public interface Pessoa{ public final static double SALMINIMO = 350; public String getNome(); public void setNome( String n ); } class Cliente implements Pessoa{ private String nome; private String tel; public void setNome( String nom ){ nome = nom ; } public String getNome(){ return nome; } public void setTelefone(String t){ tel = t; } } public class TesteInterf01{ public static void main( String[] args ){ pessoa p1 = new Cliente (); Cliente p2 = new Cliente(); p1.setNome("Maria"); // p1.setTelefone("3211-1234"); // !!Erro p2.setNome("Pedro"); p2.setTelefone("3201-3122"); imprimirNome(p1); imprimirNome(p2); if ( p1 instanceof pessoa ) System.out.println( "p1 implementa pessoa " ); if ( p1 instanceof Cliente ) System.out.println( "p1 é instancia de Cliente" ); if ( p2 instanceof pessoa ) System.out.println( "p2 implementa pessoa " ); Object obj1 = new Object(); if (!( obj1 instanceof pessoa ) ) System.out.println( "obj1 não implementa pessoa " ); System.out.println(pessoa.SALMINIMO); } private static void imprimirNome(pessoa p){ System.out.println("O Nome da pessoa é " + p.getNome() ); } } public interface funcionario{ public abstract double aumentaSalario( double s); public abstract void setSalario(double s); public abstract double getSalario(); } class Secretaria implements pessoa, funcionario{ public String getNome( ){ private String nome; return nome; } private int matricula; private double salario; public int getMatricula(){ return matricula; public Secretaria(){ } public Secretaria( String nom, int ma, double s ){ public double getSalario(){ return salario; } setNome( nom) ; public double aumentaSalario(double p){ setMatricula( ma ); setSalario(s); } public void setMatricula( int ma ){ matricula = ma; } public void setSalario( double s){ salario = s; } salario = salario*(1 + (p/100)); } public void setNome( String nom ){ nome = nom ; } return salario; } } public class TesteInterf02{ public static void main( String[] args ){ if ( p1 instanceof pessoa ) System.out.println( "p1 implementa pessoa " ); pessoa p1 = new Secretaria(); funcionario p2 = new Secretaria(); if ( p1 instanceof funcionario ) Secretaria p3 = new Secretaria(); System.out.println( "p1 implementa funcionario " ); if ( p1 instanceof Secretaria ) p1.setNome("Maria"); // p1.setMatricula("321"); // !!Erro!! System.out.println( "p1 é instancia de Secretaria" ); p2.setSalario(456); } //p2.setNome("Pedro"); // !!Erro!! private static void imprimirNome (pessoa p){ System.out.println("O Nome da pessoa é " + p.getNome() ); } p3.setNome("Joao"); p3.setSalario(223); private static void imprimirSalario p3.setMatricula(123); (funcionario p){ imprimirNome(p1); System.out.println("O salário da pessoa é " + p.getSalario() ); imprimirNome(p3); } imprimirSalario(p2); imprimirSalario(p3); } class SecretariaDepto extends Secretaria{ private String depto; public SecretariaDepto(){ } public SecretariaDepto( String nom, int ma, double s, String d){ super(nom,ma,s); setDepto(d); } public void setDepto(String d){ depto = d; } public String getDepto() { return depto; } } public class TesteInterf03{ public static void main( String[] args ){ if ( p1 instanceof SecretariaDepto ) System.out.println( "p1 é instancia de SecretariaDepto" ); pessoa p1 = new SecretariaDepto(); funcionario p2 = new SecretariaDepto(); SecretariaDepto p3 = new SecretariaDepto(); ImprimeNome in = new ImprimeNome(); in.setPessoa(p3); in.imprimir(); } p3.setNome("Joao"); p3.setSalario(223); p3.setMatricula(123); p3.setDepto("Almoxarifado"); private static void imprimirNome (pessoa p){ System.out.println("O Nome da pessoa é " + p.getNome() ); } imprimirNome(p3); imprimirSalario(p3); if ( p1 instanceof pessoa ) System.out.println( "p1 implementa pessoa " ); if ( p1 instanceof funcionario ) System.out.println( "p1 implementa funcionario " ); private static void imprimirSalario (funcionario p){ System.out.println("O salário da pessoa é " + p.getSalario() ); } } class ImprimeNome{ private pessoa p; public void setPessoa(pessoa pes){ p = pes; } public void imprimir(){ if (!(p == null)) System.out.println("O Nome da pessoa é " + p.getNome() ); } } Classes Internas São classes definidas dentro de outras classes Podem ser do tipo public, protected ou private(invisíveis para outras classes no mesmo pacote) Somente as classes internas podem ser privadas. As classes comuns sempre têm visibilidade pública ou protegida. Para criar um objeto da classe interna fora da classe externa, é necessário utilizar a sintaxe: NomeDaClasseExterna obj1 = new NomeDaClasseExterna(); NomeDaClasseExterna.NomeDaClasseInterna obj2 = obj1.new NomeDaClasseInterna() Classes Internas Para acessar a referência this da classe externa, utilize: NomeDaClasseExterna.this O objeto de classe interna tem permissão para acessar diretamente todas as variáveis de instância e os métodos do objeto da classe externa que o definiu É permitido criar uma classe interna dentro de um método Uma classe interna pode ser anônima, ou seja, não possui nome. O objeto da classe interna anônima deve ser criado no ponto em que se define a classe. A classe anônima não possui construtor, já que o construtor precisa do nome da classe. As classes anônimas são úteis quando a classe possui poucas linhas, economizando tempo e o objeto é criado apenas em um local. public interface interfCalculadora{ public double somar( double num1, double num2 ) ; public double subtrair( double num1, double num2); public double multiplicar( double num1, double num2 ); public double dividir( double num1, double num2 ); } public class tst02{ public interfCalculadora calc1 ; public static void main(String args[ ]){ tst01 obj1 = new tst01(); public tst02(){ calc1 = new interfCalculadora(){ //Classe Interna Anônima public double somar( double num1, double num2 ) { return num1 + num2; } public double subtrair( double num1, double num2){ return num1 - num2; } public double multiplicar( double num1, double num2 ){ return num1 * num2; } public double dividir( double num1, double num2 ){ return num1 / num2; } }; System.out.println( calc1.somar( 1,2) ); System.out.println( calc1.subtrair( 1,2) ); System.out.println( calc1.multiplicar( 1,2) ); System.out.println( calc1.dividir( 1,2) ); } } } public class tst03{ private String atrib1; private calculadora calc1; public static void main(String args[ ]){ tst03 obj1 = new tst03("Teste"); obj1.executaCalc(); } public tst03(String a){ atrib1=a; calc1 = new calculadora( ) ; } private void executaCalc( ){ System.out.println( calc1.somar( 1,2) ); System.out.println( calc1.subtrair( 1,2) ); System.out.println( calc1.multiplicar( 1,2) ); System.out.println( calc1.dividir( 1,2) ); System.out.println( calc1.nomeClasseInterna() ); System.out.println( calc1.nomeClasseExterna() ); System.out.println( calc1.retorneAtrib1() ); } public class calculadora implements interfCalculadora{ public calculadora(){ System.out.println("Construtor padrão de Calculadora"); } public double somar( double num1, double num2 ) { return num1 + num2; } public double subtrair( double num1, double num2){ return num1 - num2; } public double multiplicar( double num1, double num2 ){ return num1 * num2; } public double dividir( double num1, double num2 ){ return num1 / num2; } public String nomeClasseInterna(){ return getClass()+""; } public String nomeClasseExterna(){ return nomeClasse(); } public String retorneAtrib1(){ return atrib1; } } public String nomeClasse(){ return getClass()+""; } } public class tst04{ public static void main(String args[ ]){ tst03 obj1 = new tst03("Teste 03"); tst03.calculadora calc1 = obj1.new calculadora(); System.out.println( calc1.somar( 1,2) ); System.out.println( calc1.subtrair( 1,2) ); System.out.println( calc1.multiplicar( 1,2) ); System.out.println( calc1.dividir( 1,2) ); System.out.println( calc1.nomeClasseInterna() ); System.out.println( calc1.nomeClasseExterna() ); System.out.println( calc1.retorneAtrib1() ); } } Operadores Igualdade: == Diferente: != Resto da divisão: % Relacional: > , < , >= , <= Atribuição: =, +=, -=, *=, /=, %= ; Ex: se c = 2, c += 5 atribui 7 a c Incremento e Decremento: ++ , -◦ Pré-incremento Se a = 2, System.out.println( ++a ) imprime 3 Se a = 2, System.out.println( --a ) imprime 1 ◦ Pós-Incremento Se a= 2, System.out.println( a++ ) imprime 2 Se a = 2, System.out.println( a-- ) imprime 2 ◦ Se o incremento ou decremento estiver isolado, o pós e o pré-incremento apresentam o mesmo efeito; Operadores Condicional: ? ◦ Sintaxe: <condição> ? <verdadeiro> : < falso> . ◦ Ex: System.out.println( ( num % 2) = = 0 ? “Número Par”:“Número Impar”) Lógico: && (E lógico), & (E lógico booleano), || ( OU lógico), | (OU lógico booleano inclusivo), ^ (OU lógico booleano exclusivo ) e ! (NÃO lógico ). Obs.: Os operadores booleanos sempre avaliam as duas condições. Estruturas de Controle, Seleção e Repetição if ( condição ) { <comandos> } // fim do if else { <comandos> } // fim do else while ( condição ) { comandos } // fim do while Estruturas de Controle, Seleção e Repetição for ( <tipo> <var> = <valor inicial>; <condição>;<incremento>) { <comandos> } // fim do for switch( <variável>){ case <constante 1>: <comandos> break; // opcional. Encerra a estrutura switch case <constante 2>: <comandos> break; … default: // opcional. Executado se não ocorrer coincidência <comandos> } // fim do switch Estruturas de Controle, Seleção e Repetição do{ <comandos> } while ( condição ) ; Obs.: O uso das chaves ( { e } ) só é obrigatório se a estrutura possuir mais de um comando no seu corpo Instruções Break e Continue A instrução break, quando executada em uma estrutura while, for, do/while ou switch, causa a saída imediata dessa estrutura. A instrução continue, quando executada em uma estrutura while, for, ou do/while, pula as instruções restantes no corpo do laço e prossegue com a próxima iteração do laço public class ex01{ public static void main( String[ ] args ){ int a = 2 ; boolean ok = false; System.out.println( ++a ); System.out.println( a++ ); System.out.println( a ); System.out.println( --a ); System.out.println( a-- ); System.out.println( a ); System.out.println( ( a % 2 ) == 0 ? "Número Par": "Número Impar" ); switch ( a ){ case 1 : System.out.println( "a eh 1 " ); break; case 2 : System.out.println( "a eh 2 " ); break; case 3 : System.out.println( "a eh 3" ); break; case 4 : System.out.println( "a eh 4" ); break; default : System.out.println( "Nenhuma das condicoes foi satisfeita" ); } if ( a >=1 && a <= 10 ) System.out.println("a eh um numero positivo entre 1 e 10 "); if ( a > 0 || a < 0 ) System.out.println( " a nao e zero!" ); for( int j = 1; j<10; j++ ) { if (j==4) continue; else if(j==8) break; else System.out.println(j); } } } Arrays O primeiro elemento possui o número de posição zero Sintaxe: tipo_array nome_array[ ] = new tipo_array[ dim ]; ou Tipo_array[ ] nome_array = new tipo_array[ dim ] ; O tipo do array pode ser um tipo de dado primitivo ou não-primitivo O array pode ser inicializado durante a declaração, com os valores listados entre chaves e separados por vírgula. Nesse caso, o número de elementos listados determina o tamanho do array. Ex: int array[ ] = {12,6,14,30} Os arrays são tratados como objetos em Java, possuindo uma variável de instância chamada length, que indica o número de elementos. Arrays Como todo objeto, os arrays são passados para outros métodos por referência. Já os tipos primitivos de dados são passados por valor. Para um método receber um array, é necessário especificar um array como parâmetro. Ex.: public void maiorValor( int x[] ){ ... Arrays Java não suporta diretamente arrays multidimensionais, mas permite que o programador especifique arrays unidimensionais cujos elementos também são arrays unidimensionais, alcançando o mesmo efeito. Assim, o número de colunas é independente para cada linha. Ex: int b[][] = new int[3][4]; Ex: int b[][] = new int[2][]; b[0] = new int[3]; b[1] = new int[4]; import java.io.*; //Classe InputReader import java.util.*; //Classe Arrays public class ex02{ public static void main( String[ ] args ){ double[ ] vet1 = new double[4]; for(int i = 0; i < vet1.length ; i++ ) vet1[i]=lerDouble(); Arrays.sort(vet1); for(int i = 0; i < vet1.length ; i++ ) System.out.print(" I="+vet1[i]); //Vetor de duas dimensões double maior, menor, numeros[][]; numeros = new double[2][3]; System.out.println("Número de colunas: " + numeros[0].length); maior = 0; menor = 10; for(int i = 0; i < numeros.length ; i++ ) for( int j=0; j < numeros[0].length; j++ ){ System.out.println( "Digite a nota " + (j+1) + " do aluno " + (i+1) ); numeros[i][j] = lerDouble(); if ( numeros[i][j] > maior ) maior = numeros[i][j]; if ( numeros[i][j] < menor ) menor = numeros[i][j]; } System.out.println( "A maior nota foi " + maior ); System.out.println( "A menor nota foi " + menor ); //Vetor de duas dimensões com colunas diferentes double vet2[][]; vet2 = new double[2][]; vet2[0]= new double[5]; vet2[1]= new double[2]; for(int i = 0; i < vet2.length ; i++ ) for( int j=0; j < vet2[i].length; j++ ){ System.out.println( "Digite a nota " + (j+1) + " do aluno " + (i+1) ); vet2[i][j] = lerDouble(); } //Vetor de empregados empregado[ ] vet3 = new empregado[2]; vet3[0] = new empregado("Maria",43,3400.6f); vet3[1] = new gerente("João",42,3099.09f,"Maria"); imprimirEmp(vet3); } public static double lerDouble(){ try{ BufferedReader br = new BufferedReader( new InputStreamReader ( System.in ) ); String b = br.readLine() ; return Double.parseDouble( b ); } catch( Exception e ){ System.out.println( "Erro de leitura" ); return 0; } } public static void imprimirEmp (empregado[ ] x){ for(int i=0;i<x.length;i++){ System.out.println( x[i].getNome()); System.out.println("Dados Gerais: " + x[i]); if(x[i] instanceof gerente){ gerente temp = (gerente) x[i]; System.out.println("Secretária: " + temp.getSecretaria() ); } } } } Exercício: Construa uma classe em java que contenha os seguintes dados, que deverão ser todos do tipo privado, referentes a um poduto: Codigo (inteiro), Descrição (Caracter), Fabricante(Caracter), Preço (Real). A classe deverá ser desenvolvida de tal forma que o programa abaixo seja válido. Public class Exercicio{ public static void main(String arg[ ] ){ Produto pr1 = new Produto(); pr1.setCodigo(1); pr1.setDescricao(“Geladeira”); pr1.setFabricante(“Brastemp”); pr1.setPreco(1200.20); Produto pr2 = new Produto(); pr2. SetDados(2,”Frigobar”, “Consul”, 640.0); System.out.println(pr1.getCodigo() + pr1.getDescricao() + pr1.getFabricante() + pr1.getPreco() ); System.out.println(pr2.getDadosGerais() ) //Imprime todos os dados do produto } }