Questão sobre herança

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?