Dúvida com abstração

Desenvolvi algumas classes para abstrair dois tipos de documento, que no meu caso só diferem na formatação e validação: CNPJ e CPF.

As classes são as seguintes:

class Documento {
   (...)
 
   public boolean valido() {
      return true;
   }

   public static fromString(String doc) {
      if (é cnpj)
         return new CNPJ(doc);
      else if (é cpf)
         return new CPF(doc);
      else
         return new Documento(doc);
   }
}

class CNPJ extends Documento {
   (...)

   @Override
   public boolean valido() {
      return (valida cnpj);
   }
}

class CPF extends Documento {
   (...)

   @Override
   public boolean valido() {
      return (valida cpf);
   }
}

O problema é que ao usar o código abaixo, o método chamado é o da classe Documento. Eu esperava que o método chamado no exemplo abaixo fosse o da classe CPF. O método teste retornará true, apesar do CNPJ ser inválido, porque o método valido() em Documento sempre retorna true.


public boolean testaValidacao(String doc) {
   (...)
   Documento doc = Documento.fromString("236.458.322-07"); // número inválido

   assert doc instanceof CNPJ : "não é cnpj!" // passa por aqui. doc é CNPJ

   return doc.valido();
}

Como proceder esta abstração neste caso?

Seu método “é cpf” não está retornando true para seu conjunto de dados, portanto fromString retorna um new Documento(), não um new CPF(). Para funcionar do jeito que você quer, faça o método “valido” da classe Documento retornar false, não true.

Opa, thingol… sempre presente!

Eu coloquei a linha abaixo justamente para evitar essa situação.

assert doc instanceof CNPJ : "não é cnpj!" // passa por aqui. doc é CNPJ  

E também se eu debugar este código, vejo que ele vai direto para Documento.valido() mesmo.

thingol, matou à mau. Era isso mesmo. Desculpe a falta de cuidado com os códigos postados.