~~SLIDESHOW~~ ====== Java com Objetos ====== ==== Java com classe ==== Por João Araujo (adaptado do curso de Oscar Farias). ===== Estrutura de um Programa em JAVA (i)===== * Um programa em JAVA é composto de **classes** * Apenas uma classe implementa o método** main()**. * As classes em JAVA podem estar em múltiplos arquivos (**compilation units**) * Cada arquivo fonte termina com o sufixo **.java** ===== Estrutura de um Programa em JAVA (ii)===== * Cada classe contém **data members** (declarações de tipos de dados) e **methods** (funções que operam nos data members da classe) * O conjunto de classes em uma unidade de compilação pode fazer parte de um mesmo **package**. Isto significa que todas as classes serão pré-fixadas com o nome do package. * O comando **import** instrui o compilador para carregar uma determinada classe que está em uma outra unidade de compilação. * O comando **interface** especifica um conjunto de métodos que descrevem, em alto nível, um comportamento determinado. ===== Classes e Objetos ===== * A Classe é a unidade fundamental de programação * Cada programa é escrito como uma coleção de classes * As definições de classes são armazenadas em arquivos separados com a extensão .java e o nome do arquivo deve ser o mesmo da classe * Uma classe é uma descrição de um grupo de entidades que possuem as mesmas características * Cada entidade é um objeto ===== Classes e Objetos em Java ===== * **Classes** são os templates para especificar o estado e comportamento de um **objeto** em tempo de execução. * **Objeto** é uma instância de uma classe. * Classes consistem de **atributos** e **métodos**. * Após a definição de uma classe, pode-se criar os objetos correspondentes com o operador **new**. ===== Operador new ===== * O operador **new**: * aloca memória para o objeto * inicializa variáveis de instância * chama um **construtor** ===== Construtores ===== * **Construtores** são métodos que são chamados quando o objeto é instanciado. * Provêem inicializações adicionais para o objeto. ===== Métodos===== * Métodos: especificam o comportamento dos objetos * Os métodos possuem duas partes: definição e corpo. * Definição: Possui três componentes:valor retornado, o nome do método e uma lista de parâmetros * **Corpo**: algoritmo que opera sobre os dados. * Os métodos podem declarar variáveis locais. * Os métodos podem ser sobrecarregados (em particular, os construtores) - **Overloading** ===== Sobrecarga (Overload) (i)===== Métodos com o mesmo nome para diferentes classes Solução: qualificar o nome por completo. void fn(TV mytv, Radio myradio) { mytv.ChangeChannel(); //troca o canal da tv myradio.ChangeChannel(); //troca a estação do radio } ===== Sobrecarga (ii)===== Quando o método é chamado de dentro da classe não é necessária a qualificação completa class TV { void ChangeChannel() { //código do método ... } void SomeFunction() { ChangeChannel(); } } ===== Sobrecarga (iii)===== Métodos com o mesmo nome para a mesma classe Solução: a distinção entre os métodos é feita através dos argumentos class BankAccount { double m_dCurrentInterestRate; // the Account’s interest rate double Rate(){ // Rate - inquire or set interest rate return m_dCurrentInterestRate; } double Rate(double dNewRate) { if (dNewRate > 0.0 && dNewRate < 20.0) { m_dCurrentInterestRate = dNewRate; } } ===== Sobrecarga (iv)===== ... BankAccount baMyAccount ... baMyAccount.Rate (0.8); // estabelece a taxa* baMyAccount.Rate (): // recupera a taxa corrente ... ===== Sobrecarga (Overload) (v)===== Não é possível diferenciar dois métodos apenas em função do valor retornado. class RealNumber { // convert current RealImaginary number to a double double Convert (); //convert current RealImaginary number to a int int Convert (); } // Dá origem ao seguinte problema: void Fn(RealNumber rn) { rn.Convert (); // qual dos Convert devo usar??? } ===== Sobrecarga em construtores===== public class PairOfDice { public int die1; //Number showing on the first die. public int die2; //Number showing on the second die. public PairOfDice() { //Constructor. Rolls the dice, so that they initially //show some random values . roll();//Call the roll( ) method to roll the dice. } public PairOfDice(int val1, int val2) { // Constructor. Creates a pair of dice that // are initially showing the values val1 and val2 . die1 = val1; / / Assign specified values die2 = val2; //to the instance variables. } } //end class PairOfDice ===== Herança ===== * Uma classe pode herdar características de outra classe. * Uma classe existente pode ser estendida para criar uma subclasse. public class Subclass−name extends Existing−class−name { . . //Changes and additions. . } ===== Herança e Hirarquia de Classes ===== {{:carac:java8.png|}} ===== Herança e Java ===== class B extends A { . . // adições e modificações das . // do que foi herdado de A. . } ===== Hirarquia de classes ===== {{:carac:java9.png|}} ===== Exemplo: Veículos ===== {{:carac:java10.png|}} ===== Classe Veiculo ===== class Vehicle { int registrationNumber; Person owner; //( Assuming that a Person class has been defined!) void transferOwnership(Person newOwner) { . . . } . . . } ===== Subclasses ===== class Car extends Vehicle { int numberOfDoors; . . . } class Truck extends Vehicle { int numberOfAxels; . . . } class Motorcycle extends Vehicle { boolean hasSidecar; . . . } ===== Objetos e herança ===== Um objeto que possa guardar referência a um objeto da classe A, também pode guardar uma referência a qualquer objeto das suas subclasses. * Vehicle myVehicle = myCar; * Vehicle myVehicle = new Car(); ===== instanceof ===== Podemos usar instanceof para descobrir se um objeto pertence a uma classe. if (myVehicle instanceof Car) ... ===== Polimorfismo ===== Vamos criar as classes Retangles, Ovals e RoundRects como sublasses de Shape. {{:carac:java11.png|}} ===== Classe Shapes ===== class Shape { Color color; //Color of the shape. (Recall that class Color //is defined in package java.awt.Assume //that this class has been imported.) void setColor(Color newColor) { // Method to change the color of the shape . color = newColor; //change value of instance variable redraw(); // redraw shape , which will appear in new color } void redraw() { // method for drawing the shape ??? // what commands should go here ? } ... //more instance variables and methods } / / end of class Shape ===== Subclasse rectangle ===== class Rectangle extends Shape { void redraw() { ...//commands for drawing a rectangle } ...//possibly, more methods and variables } ===== Coleta de Lixo (i)===== * Além do gerenciamento de objetos em memória o Java run-tyme system mantém um registro de todas as referências aos objetos. * Quando um objeto não é mais referenciado ele é automaticamente removido da memória. * O programador é liberado da tarefa de retornar ao espaço disponível os objetos que foram previamente alocados. ===== Coleta de Lixo (i)===== * O **Garbage Collector** é executado como um thread de baixa prioridade nos momentos em que a máquina encontra-se inativa. * A área de memória ocupada pelos objetos não é necessariamente liberada de imediato. ===== Membros Estáticos ===== **Class Members**: são propriedades que são compartilhadas por todos objetos de uma mesma classe. São também chamados de membros estáticos class Bank Account; { // a taxa de juros é para ser compartilhada por // todas as contas bancárias. static double m_dCurrentInterestRate; ... } ===== Modificadores de Acesso ===== Controlam o nível de visibilidade que os métodos e data members de uma classe terão para as outras classes: Public, Protected, Private e Package ===== Public ===== indica que se pode ter acesso ao método ou data member assim declarado em uma dada classe X, a partir de qualquer classe ou método que tenha visibilidade da classe X. ===== Protected ===== o acesso é restrito apenas às subclasses da classe protected. ===== Private ===== o método ou data member não está disponível para qualquer outra classe, exceto para aquela onde ele aparece. ===== Package ===== é o acesso default. Não corresponde diretamente a uma keyword de acesso. Quando se cria um package (biblioteca de classes), se não se especifica um modificador de acesso para um dado método ou dado, todas as outras classes do package poderão ter acesso ao mesmo. ===== Um programa simples com classe ===== Vamos modelar uma conta bancária? ===== Os atributos ===== O que uma conta possui e é importante para nosso modelo? * número da conta * nome do cliente * saldo * limite ===== Métodos ===== O que toda conta faz? O que gostaríamos de “pedir à conta”?. * saca uma quantidade x * deposita uma quantidade x * imprime o nome do dono da conta * devolve o saldo atual * transfere uma quantidade x para uma outra conta y * devolve o tipo de conta ===== Classes e Objetos ===== {{:carac:java12.png|}} ===== O que a conta tem ===== class Conta { int numero; String nome; double saldo; double limite; // .. } ===== Criando uma instância ===== class Programa { public static void main(String[] args) { new Conta(); } } ===== Uma variável ===== Variável **minhaConta** class Programa { public static void main(String[] args) { Conta minhaConta; minhaConta = new Conta(); } } ===== Programa ===== class Programa { public static void main(String[] args) { Conta minhaConta; minhaConta = new Conta(); minhaConta.nome = "Carlos"; minhaConta.saldo = 1000.0; System.out.println("Saldo atual: " + minhaConta.saldo); } } ===== Método saca() ===== class Conta { double salario; // ... outros atributos ... void saca(double quantidade) { double novoSaldo = this.saldo - quantidade; this.saldo = novoSaldo; } } ===== Método deposita() ===== class { // ... outros atributos e métodos ... void deposita(double quantidade) { this.saldo += quantidade; } } ===== Método saca() melhorado ===== boolean saca(double valor) { if (this.saldo < valor) { return false; } else { this.saldo = this.saldo - valor; return true; } } ===== Modelo UML ===== {{:carac:java13.png|}} ===== Exemplo de uso ===== minhaConta.saldo = 1000; boolean consegui = minhaConta.saca(2000); if(consegui){ System.out.println("Consegui sacar"); }else{ System.out.println("Não consegui sacar"); } ===== Objetos são acessados por referências ===== public static void main(String args[]) { Conta c1; c1 = new Conta(); Conta c2; c2 = new Conta(); } ===== Graficamente ===== {{:carac:java14.png|}} ===== O que acontece? ===== class TestaReferencias { public static void main(String args[]) { Conta c1 = new Conta(); c1.deposita(100); Conta c2 = c1; // linha importante! c2.deposita(200); System.out.println(c1.saldo); System.out.println(c2.saldo); } } ===== Graficamente ===== {{:carac:java15.png|}} ===== Comparando referências ===== public static void main(String args[]) { Conta c1 = new Conta(); c1.nome = "Duke"; c1.saldo = 227; Conta c2 = new Conta(); c2.dono = "Duke"; c2.saldo = 227; if (c1 == c2) { System.out.println("Contas iguais"); } } ===== São diferentes! ===== {{:carac:java16.png|}} ===== Método transfere() ===== Qual o problema deste código? void transfere (Conta conta1, Conta conta2, double valor) { } ===== Método transfere() correto ===== void transfere(Conta destino, double valor) { this.saldo = this.saldo - valor; destino.saldo = destino.saldo + valor; } ===== em UML ===== {{:carac:java17.png|}} ===== Método transfere() ainda melhor ===== boolean transfere(Conta destino, double valor) { boolean retirou = this.saca(valor); if (retirou == false) { // não deu pra sacar! return false; } else { destino.deposita(valor); return true; } } ===== em UML ===== {{:carac:java18.png|}} ===== Classe Cliente ===== class Cliente { String nome; String sobrenome; String cpf; } ===== Aprimorando Conta ===== class Conta { int numero; double saldo; double limite; Cliente titular; // .. } ===== Testando tudo ===== class Teste { public static void main(String[] args) { Conta minhaConta = new Conta(); Cliente c = new Cliente(); minhaConta.titular = c; // ... } } ===== Acesso ao cliente ===== Cliente clienteDaMinhaConta = minhaConta.titular; clienteDaMinhaConta.nome = "Duke"; Ou minhaConta.titular.nome = "Duke"; ===== Carga inicial de Cliente ===== class Conta { int numero; double saldo; double limite; Cliente titular = new Cliente(); } ===== Em UML ===== {{:carac:java19.png|}} ===== Controle de Acesso ===== A função saca() de Conta pode deixar a conta com saldo abaixo do limite. public static void main(String args[]) { Conta minhaConta = new Conta(); minhaConta.limite = 100; minhaConta.saldo = -200; //saldo está abaixo dos 100 de limite } Como resolver? ===== Testando? ===== public static void main(String args[]) { // a Conta Conta minhaConta = new Conta(); minhaConta.limite = 100; minhaConta.saldo = 100; // quero mudar o saldo para -200 double novoSaldo = -200; // testa se o novoSaldo ultrapassa o limite da conta if (novoSaldo < -minhaConta.limite) { // System.out.println("Não posso mudar para esse saldo"); } else { minhaConta.saldo = novoSaldo; } } ===== A resposta é... ===== Declarando os atributos "private" class Conta { private double saldo; private double limite; // ... } ===== Protegemos os atributos ===== class TestaAcessoDireto { public static void main(String args[]) { Conta minhaConta = new Conta(); //não compila! você não pode acessar o atributo privado de outra classe minhaConta.saldo = 1000; } } ===== Método public ===== Para todos terem acesso: public void saca(double quantidade) { if (quantidade > this.saldo + this.limite){ //posso sacar até saldo+limite System.out.println("Não posso sacar fora do limite!"); } else { this.saldo = this.saldo - quantidade; } } ===== private e public ===== * Métodos em geral são públicos, a não ser os métodos internos. * Atributos são private, e são manipulados apenas pelos métodos da classe. ===== Encapsulamento ===== * O encapsulamento esconde detalhes internos de uma classe. * É fundamental para segurança e flexibilidade do código. ===== Exemplo geral ===== public static void playGame() { // "public" and "static" are modifiers; "void" is the // return-type; "playGame" is the subroutine-name; // the parameter-list is empty. . . . // Statements that define what playGame does go here. } ===== Public ===== * Quer dizer que a função pode ser invocada fora da classe. * Variáveis public podem ser modificadas fora da classe. * Se nada for dito, a variável pode ser modificada pelas classes do **package**. ===== Sem modificadores ===== int getNextN(int N) { // There are no modifiers; "int" in the return-type // "getNextN" is the subroutine-name; the parameter-list // includes one parameter whose name is "N" and whose // type is "int". . . . // Statements that define what getNextN does go here. } ===== Static ===== * os valores das variavéis static são iguais entre instâncias diferentes e o valor das restantes variáveis são diferentes. * métodos static precisam de uma instância para executar. * Métodos não static podem ser invocados em existir uma instância. ===== Construtor ===== * O método construtor é chamado na carag inicial do objeto e inicia os atributos relativos à Classe. * Tem o mesmo nome da Classe. Conta() { System.out.println("Construindo uma conta."); } ===== Fim ===== That's all folks! {{:carac:that_sall.jpg|}}