View page as slide show

Java com Objetos

Java com classe

Por João Araujo (adaptado do curso de Oscar Farias).

Estrutura de um Programa em JAVA (i)

Estrutura de um Programa em JAVA (ii)

Classes e Objetos

Classes e Objetos em Java

Operador new

Construtores

Métodos

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

public class Subclass−name
  extends Existing−class−name {
    .
    .   //Changes and additions.
    .
}

Herança e Hirarquia de Classes

Herança e Java

class B extends A {
    .
    . // adições e modificações das 
    . // do que foi herdado de A.
    .
}

Hirarquia de classes

Exemplo: Veículos

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.

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.

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)

Coleta de Lixo (i)

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?

Métodos

O que toda conta faz? O que gostaríamos de “pedir à conta”?.

Classes e Objetos

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

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

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

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!

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

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

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

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

Encapsulamento

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

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

Construtor

Conta() {
    System.out.println("Construindo uma conta.");
}

Fim

That's all folks!