Bom dia. Estou enfrentando um questionamento, mas gostaria de maiores explicações sobre o caso que segue abaixo.
Se possuo uma classe Arvore
class Arvore{
public String folha;
public String tronco;
public String raiz;
}
E possuir uma classe Pinheiro
class Pinheiro extends Arvore{
public void plantar(){
System.out.println("Plantei um pinheiro");
}
}
Em um método Main por que dá erro?
public class Main {
public static void main(String args[]){
Arvore arvore = new Pinheiro();
arvore.plantar();
//((Pinheiro)arvore).plantar();
}
}
Por que você não disse que a árvore possui a operação de plantar. Se quiser fazer isso funcionar, faça:
public abstract class Arvore{
public String folha;
public String tronco;
public String raiz;
public abstract void plantar();
}
Assim vc diz que a classe possui um método plantas, mas que ele ainda não é definido. Só será nas subclasses.
Quando vc faz:
Arvore arvore = new Pinheiro();
Na memória HEAP do Java é criado um objeto do tipo Pinheiro e cria uma referência para esse objeto, jogando na variável arvore, certo? Porém, quais informações você possui acesso? Somente as informações de árvore. No seu exemplo, o comportamento (método) de plantar só faz parte da classe Pinheiro, portanto, a classe Árvore não conhece esse ele. Por isso não funciona.
O que faz funcionar é se Árvore também souber como plantar. Na verdade, é melhor que este comportamento esteja em Árvore, pois todas elas têm de ser plantadas, certo? Agora, se alguma árvore possuir um comportamento de plantio diferente, você sobrescreve o comportamento.
Aí sim, voltando ao seu exemplo:
Arvore arvore = new Pinheiro();
Quando você tentar acessar o comportamento de plantar, ele vai ao comportamento de Pinheiro ao invés de Árvore, porque? Porque, em termos de métodos, o java primeiro verifica nas subclasses se existe esse comportamento. Se existir, ele executa este. Se não, ele executa o da superclasse.
EDIT: Ops. Botão errado. Apertei citar ao invés de editar. Desculpem.
Obrigado pelas respostas.
Uma situação problema. No caso do método plantar estar presente apenas em Pinheiro e na classe Pitangueira não. Qual seria a abstração para este caso?
Se vc colocar o método abstrato, você é obrigado a implementá-lo em todas as subclasses. O que você pode fazer é ter duas novas classes. Exemplo:
ArvoresPlantadas e ArvoresArtificiais
As duas herdam de arvore, mas somente a classe ArvoresPlantadas vai possuir o metodo plantar abstrato, obrigando suas filhas a plantarem. Entendeu?