Fala cara,
Eu sou meio contra herança (heresia!!!).
Existem dois motivos para se usar herança, o mau e o bom. O mau motivo é usar herança pra fazer reuso de código: “bem, se estas duas classes aqui têm um método calculatePrice()” que é igual, então vou criar uma classe base AbstractPriceable e botar o método nela!!".
Este é um mau motivo porque você acopla duas classes que não deveriam ter nada a ver uma com a outra. Só se deve fazer herança quando houver uma relação “É-UM”. Um exemplo de livro-texto: você pode ter a classe base Shape, e a classe filha Circle extends Shape. Isso porquê Circle “É-UM” Shape E você tem situações legítimas onde você quer trabalhar com objetos Shape de maneira genérica sem se importar se ele é um Circle, Square ou Rectangle – apesar de que eu prefereria usar interfaces neste caso.
No seu exemplo, a princípio parece fazer sentido que Cliente “É-UM” Usuario.
Mas será que Usuario é realmente a abstração em comum de Cliente, Vendedor e Fornecedor? Você mesmo diz que Cliente não se loga no sistema. Acho que você está escolhendo a abstração errada para a classe base. Há situações onde você precisa usar a classe Usuario de maneira genérica, não importando se a classe concreta é Cliente, Vendedor ou Fornecedor? Mesmo que a resposta for SIM, você pode considerar usar interfaces ao invés de herança.