terça-feira, 6 de abril de 2010

[Java] Definir herança, polimorfismo, sobrecarga, sobrescrita e invocação de método virtual (parte 1/3)


Herança

É comum em programação orientada a objetos a criação de um modelo para alguma coisa (por exemplo um Animal), e depois precisar de um modelo especializado do original. Por exemplo, pode ser necessária a modelagem de um Peixe ou de um Cavalo que seriam um tipo de Animal, porém com algumas características a mais ou diferenciadas.

Considere o exemplo abaixo.
public class Animal {

public String habitoAlimentar = "";
public String reproducao = "";
public double pesoMedio = 0.0;

public Animal(){}

public Animal(String habitoAlimentar, String reproducao,
double pesoMedio){
...
}

public String detalhaAnimal(){
...
}
}

public class Cavalo {

public String habitoAlimentar = "";
public String reproducao = "";
public double pesoMedio = 0.0;

public String raca = "";
public String corPelagem = "";

public Cavalo(){}

public Cavalo(String habitoAlimentar, String reproducao,
double pesoMedio, String raca, String corPelagem){
...
}

public String detalhaAnimal(){
...
}

}
Percebe-se pelo exemplo que houve a duplicação de variáveis entre as classes Animal e Cavalo. Além disso pode também existir vários métodos que sejam válidos para ambos. Para evitar esse tipo de repetições desnecessárias é recomendada a criação de subclasses daquelas já existentes (utilização de herança).

Em linguagens orientadas a objeto o mecanismo da herança permite ao programador definir uma classe com termos de uma classe anteriormente definida. Em java é utilizada a palavra-chave extends para este propósito como mostra o exemplo abaixo.
public class Cavalo extends Animal {
private String raca = "";
private String corPelagem = "";
}
Descrevendo a classe Cavalo como "é um" Animal não é apenas um modo conveniente de descrever a relação entre as duas classes faz com que o programador se lembre que Cavalo tem todos os membros, tanto atributos como métodos, da classe pai Animal. Isso também significa que se uma operação é válida para Animal então ela também é válida para Cavalo. Assim se a classe pai Animal possui o método detalhaAnimal a classe Cavalo também a possui.

Veja abaixo como seria o diagrama de classe para as classes Animal e Cavalo usando herança.



Sintaxe para uma classe que herda outra:
[modificador] class [nomeDaClasse] extends [nomeDaClassePai]{
[declarações]
}
Vale lembrar que uma herança em Java os contrutores não são herdados, assim se uma classe pai não houver um construtor padrão (sem parâmetros) a classe filha deve implementar uma chamada ao construtor da classe pai com os parâmetros necessários para o contrutor da classe pai. Exemplo: Se a classe pai possui apenas um construtor na forma pai(int x){} a classe filha deve obrigatoriamente implementar um construtor da seguinte forma: filha(int n){ super(n) }

Herança Simples


A linguagem de programação Java permite que uma classe extenda apenas a uma outra classe. A esta restrição damos o nome de Herança simples. Apesar de possiur a restrição de herança simples, java pode realizar tarefa semelhante a herança múltipla com a utilização de interfaces da seguinte forma:
  • Uma classe implementando várias interfaces
  • Uma interface extendendo várias interfaces
Interfaces

Interfaces são conjuntos de métodos vazios (não implementados) e constantes. As interfaces não possuem atributos e interfaces são, de forma simplificada, como roteiros a serem seguidos pelas classes que a implementam. Quando uma classe implementa certa interface ela deve implementar cada um dos seus métodos.

[Java] Passar argumentos para o método principal para uso em um programa


Após todos estes posts pode-se perceber que a base de um programa Java possui a seguinte estrutura:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
No blog já foi explicado o significado das palavras-chave public, static e void. Porém ainda não foi explicado sobre as palavras-chave main e este vetor args que é passado como parâmetro para o método main. A palavra-chave main serve para indicar ao compilador que este método chamado main será o executável. O vetor de String args passado como argumento para este método main pode ou não ser utilizado. Para passar argumentos (parâmetros) para o método main basta fazer como no exemplo abaixo.

java HelloWorld [argumento1] [argumento2] [argumento3]

Agora como utilizar este argumento no método main? Muito simples! Como foi dito anteriormente os argumentos são na verdade um vetor de String chamado args, então para utilizá-lo é exatamente da mesma forma que utilizamos matrizes unidimensionais (vetores). Veja um exemplo do uso de argumentos abaixo.
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
if (args.length>0)
System.out.println(args[0]);
}
}
Lembre-se sempre de verificar se a posição do vetor de argumentos que você deseja utilizar é existente. Como não é obrigatória a passagem de argumentos, se você em seu programa não fizer essa verificação e tentar utilizar alguma posição não existente o programa retornará um erro de estouro de vetor (Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: [númeroDaPosiçãoInexistente]).

[Java] Criar uma matriz multidimensional


Da mesma forma que funcionam as matrizes de matrizes que vimos neste post. Matrizes multidimensionais são matrizes de matrizes com mesmo tamanho. Ficou complicado? Então observe a figura abaixo.


Para melhorar a visualização, utilizade e usabilidade de uma matriz multidimensional procure entende-la como uma tabela. Assim, esta mesma matriz mostrada acima seria entendida da seguinte forma.


As matrizes com duas e três dimensões são as mais utilizadas no dia-a-dia. Entretanto, matrizes multidimensionais podem ter, obviamente, mais de três dimensões. Para declarar matrizes de três ou mais dimensões deve-se apenas acrescentar mais colchetes em sua declaração. Veja o exemplo abaixo de uma matriz com quatro dimensões para compreender melhor.
int[][][][] matrizQuatroDimensoes = new int [2][2][2][2];
A matriz deste exemplo pode ser vista da seguinte forma.


Matrizes multidimensionais também pode ser declarada e inicializada de forma simplificada. Considerando uma matriz com quatro dimensões, veja o exemplo abaixo.

int matrizQuatroDimensoes[][][][]={ { {{1, 2},{3, 4}},
{{5, 6},{7, 8}}
},
{ {{9, 10},{11, 12}},
{{13, 14},{15, 16}}
}
}
Lembrando que você não precisa colocar tantos espaços e quebra de linhas como foi feito acima. Fiz dessa forma apenas para melhor vizualizar.