PROGRAMAÇÃO COM OBJECTOS A CLASSE "Class" Nuno Mamede Programação com Objectos ÍNDICE ♦ Introdução aos objectos ♦ Polimorfismo ♦ Tudo é um objecto ♦ Interfaces e classes internas ♦ Instruções de controlo ♦ Guardar os objectos ♦ Iniciação e limpeza ♦ Tratamento de erros ♦ Esconder a realização ♦ Entradas / Saídas ♦ Reutilização de classes ♦ A CLASSE "Classe" ♦ Padrões de desenho Licenciatura em Engenharia Informática e de Computadores Departamento de Engenharia Informática Instituto Superior Técnico OBJECTIVOS OPERACIONAIS ✏ Utilizar a classe "Classe" -2- © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. Programação com Objectos ENTRADAS / SAÍDAS do Java, para descobrir a classe de um objecto ✏ Usar o mecanismo de reflexão do Java para descobrir, durante a execução, informação sobre uma classe ♦ A classe "Class" ♦ RTTI ♦ Reflection ♦ Compilação -3- © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. -4- © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. A CLASSE "Class " "Class" — Class.forName() — A CLASSE "Class " "Class" class Goma { static {System.out.println("Carregando Goma");} } ✏ Um objecto (instância de) "Class": ● Contém informação sobre uma classe ● Existe um objecto destes por cada classe participante no programa ● Guardado num ficheiro com extensão ".class", que só é carregado quando necessário ● Depois de estar em memória, é usada para criar instâncias ✏ Para obter uma referência para uma classe (um objecto): ● Class.forname("Gato") (é um literal) gerar excepção IllegalAccessException ● Gato.class ● Pode -5- © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. class Bolacha { static {System.out.println("Carregando Bolacha");} } public class LojaDoces { public static void main(String[] args) { System.out.println("Dentro do main"); new Bolacha(); System.out.println("Depois de carregar Bolacha"); try { Class.forName("Goma"); } catch(ClassNotFoundException e) { e.printStackTrace(System.err); } System.out.println("Depois Class.forName(\"Goma\")"); } // Dentro do main } // Carregando Bolacha // Depois de carregar Bolacha // Carregando Goma // Depois Class.forName("Goma") -6- RUN TIME TYPE IDENTIFICATION (RTTI) — reconhecimento parcial — Programação com Objectos ENTRADAS / SAÍDAS ♦ A classe "Class" © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. // Ficheiro: Gato.java public class Gato { private int _numeroGato; Gato(int i) { _numeroGato = i; } void print() { System.out.println("Gato #" + _numeroGato); } } ♦ RTTI // Ficheiro: Cao.java public class Cao { private int _numeroCao; Cao(int i) { _numeroCao = i; } void print() { System.out.println("Cão #" + _numeroCao); } } ♦ Reflection ♦ Compilação -7- © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. -8- © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. RUN TIME TYPE IDENTIFICATION (RTTI) — reconhecimento parcial (cont.) — RUN TIME TYPE IDENTIFICATION (RTTI) — instanceof — ✏ instanceof // Ficheiro: CaesEGatos.java import java.util.ArrayList; ●É uma palavra reservada que indica se um objecto é uma instância de um determinado tipo ● Por exemplo: (x instanceof Gato) public class CaesEGatos { public static void main(String[] args) { ArrayList gatos = new ArrayList(); for(int i = 0; i < 7; i++) gatos.add(new Gato(i)); ● Só // Não há nenhum problema em guardar este cão gatos.add(new Cao(7)); // O "cão" gera uma excepção durante a execução for(int i = 0; i < gatos.size(); i++) ((Gato)gatos.get(i)).print(); } } // // // // // // // Gato Gato Gato Gato Gato Gato Gato pode ser usado com o nome de uma classe – não pode ser usado com uma instância de Class – Não pode ser usado para comparar com os elementos de um vector #0 #1 #2 #3 #4 #5 #6 Exception in thread "main" java.lang.ClassCastException at CaesEGatos.main(CaesEGatos.java:16) -9- © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. - 10 - © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. RUN TIME TYPE IDENTIFICATION (RTTI) — instanceof (cont.) — RUN TIME TYPE IDENTIFICATION (RTTI) — instanceof (cont.) — import java.util.ArrayList; import java.util.ArrayList; public class CaesEGatos2 { public static void main(String[] args) { public class CaesEGatos3 { public static void main(String[] args) { int g=0, c=0; ArrayList gatos = new ArrayList(); ArrayList gatos = new ArrayList(); for(int i = 0; i < 7; i++) gatos.add(new Gato(i)); for(int i = 0; i < 7; i++) gatos.add(new Gato(i)); gatos.add(new Cao(7)); for(int i = 0; i < gatos.size(); i++) if (gatos.get(i) instanceof Gato) ((Gato)gatos.get(i)).print(); else ((Cao)gatos.get(i)).print(); } } - 11 - gatos.add(new Cao(7)); // // // // // // // // Gato Gato Gato Gato Gato Gato Gato Cão #0 #1 #2 #3 #4 #5 #6 #7 © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. for(int i = 0; i < gatos.size(); i++) { if (gatos.get(i) instanceof Gato) g++; if (gatos.get(i) instanceof Cao) c++; } System.out.println("Gatos = " + g); System.out.println("Cães = " + c); } } - 12 - // Gatos = 7 // Cães = 1 © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. RUN TIME TYPE IDENTIFICATION (RTTI) — instanceof (cont.) — VERIFICAÇÃ O DO TIPO DE UM OBJECTO VERIFICAÇÃO ✏ (Gato.class).isInstance(object) ● (Gato.class)é ✏ (Object import java.util.ArrayList; um literal de Class (instância da class Class) instanceof Gato) public class CaesEGatos4 throws ClassNotFoundException{ public static void main(String[] args) { int g=0, c=0; ArrayList gatos = new ArrayList(); ✏ Para os objectos primitivos for(int i = 0; i < 7; i++) gatos.add(new Gato(i)); ● boolean.class ● char.class gatos.add(new Cao(7)); ● byte.class for(int i = 0; i < gatos.size(); i++) { if (Gato.class.isInstance(gatos.get(i)) ) g++; if (Class.forName("Cao").isInstance(gatos.get(i)) ) c++; } ● short.class ● int.class ● long.class System.out.println("Gatos = " + g); System.out.println("Cães = " + c); ● ... } // Gatos = 7 // Cães = 1 } - 13 - © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. - 14 - © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. Programação com Objectos ENTRADAS / SAÍDAS INFORMAÇÃ O SOBRE UMA CLASSE INFORMAÇÃO ✏ Alguns métodos da classe Class: ● static ClassforName(String className) ● Class getComponentType() Package getPackage() ● public Class[] getInterfaces() ● public ♦ A classe "Class" ♦ RTTI ● Constructor ♦ Reflection ● Class[] getDeclaredClasses() getDeclaredMethods() ● Field getDeclaredField(String name) ♦ Compilação ● Method[] ● int - 15 - getConstructor(Class[] parameterTypes) getConstructors() ● Constructor[] © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. - 16 - getModifiers() © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. java.lang java.lang..reflect java.lang java.lang..reflect. reflect.Constructor ✏ Alguns métodos da classe Constructor: ✏ Define as classes (entre outras): ● Method ● Constructor ● public ● Field ● public ● Modifier ● public ● ReflectPermission ● public ● public ✏ É possível (por vezes ...): ● public ● public ● Inspeccionar Class getDeclaringClass() String getName() int getModifiers() Class[] getParameterTypes() Class[] getExceptionTypes() String toString() Object newInstance(Object[] initargs) ● Alterar ● Executar - 17 - © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. - 18 - © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. java.lang java.lang..reflect. reflect.Method ✏ Alguns métodos da classe Method: ● public ● public ● public ● public ● public ● public ● public - 19 - java.lang java.lang..reflect. reflect.Constructor ✏ Alguns métodos da classe Constructor: Class getDeclaringClass() String getName() int getModifiers() Class[] getParameterTypes() Class[] getExceptionTypes() String toString() Object newInstance(Object[] initargs) © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. ● public ● public ● public ● public ● public ● public ● public - 20 - Class getDeclaringClass() String getName() int getModifiers() Class[] getParameterTypes() Class[] getExceptionTypes() String toString() Object newInstance(Object[] initargs) © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. REFLECTION — getDeclaredConstructor()— — REFLECTION — getDeclaredConstructor() import java.lang.reflect.Constructor; import java.util.ArrayList; for(int i = 0; i < gatos.size(); i++) if (gatos.get(i) instanceof Gato) ((Gato)gatos.get(i)).print(); else ((Cao)gatos.get(i)).print(); public class CaesEGatos5 { public static void main(String[] args) { } ArrayList gatos = new ArrayList(); for(int i = 0; i < 7; i++) gatos.add(new Gato(i)); try { Class caoClass = Cao.class; Class[] types = {int.class}; Object[] argumentos = {new Integer(7)}; } // // // // // // // // Constructor consC = caoClass.getDeclaredConstructor(types); Cao newCao = (Cao) consC.newInstance(argumentos); gatos.add(newCao); } catch (Exception e ) { e.printStackTrace(); } - 21 - (cont.) — © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. - 22 - #0 #1 #2 #3 #4 #5 #6 #7 © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. Programação com Objectos ENTRADAS / SAÍDAS Gato Gato Gato Gato Gato Gato Gato Cão java.lang java.lang..Compiler ✏A classe Compiler permite compilar uma classe (durante a execução): ● public static boolean compileClass(Class class) ● public static boolean compileClasses(String string) ♦ A classe "Class" ♦ RTTI ♦ Reflection ♦ Compilação - 23 - © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. - 24 - © 2003 Nuno J. Mamede, IST, DEI. All rights reserved. Programação com Objectos ENTRADAS / SAÍDAS ♦ A classe "Class" ♦ RTTI ♦ Reflection ♦ Compilação - 25 - © 2003 Nuno J. Mamede, IST, DEI. All rights reserved.