Preciso criar uma estrutura de classes, onde existirá Funcionario, Gerente e Diretor.
Qual a melhor abordagem para a classe Funcionario? Um classe abstrata ou uma interface?
Preciso criar uma estrutura de classes, onde existirá Funcionario, Gerente e Diretor.
Qual a melhor abordagem para a classe Funcionario? Um classe abstrata ou uma interface?
Você poderia ter colocado algum código do que acha! em cima disso poderíamos ajudar!
Bom dia!
Depende de como você quer tratar esta informação dentro de sua aplicação, pois existem “N” maneiras de se fazer, em uma aplicação que tenho, eu trato isso em uma interface de Cadastro de Funcionário, e nesta interface eu tenho um indicador para saber se a pessoa que está sendo cadastrada se encaixa nas categorias (Funcionário Comum, Gerente ou Diretor), e conforme o indicador selecionado eu trato as informações necessárias para cada um.
Não fiz nada ainda kkkkkkkkk Vou começar e por isso a dúvida… Mas imagine algo bem simples mesmo… A duvida esta na melhor forma de generalizar o Funcionario. Se através de uma classe abstrata ou de uma interface.

A minha intenção é generalizar ao maximo… pq…vou ter métodos que precisarei receber funcionarios. Mas se Funcionario for uma classe abstrata, não conseguirei correto? Precisarei mandar ou um diretor ou um gerente. A menos que eu receba uma interface funcionario e possa enviar tanto gerente, quanto diretor. Por que a minha preocupação, é que la na frente, ao surgir outro tipo de funcionario, eu nao precise mexer no codigo.
Você vai usar funcionário somente como base ou ela também coexistirá no seu código e regra de negócio como alguma entidade?
Só como base… ou é um gerente ou é um diretor… a regras de negócio se baseiam em gerente e diretor…
Eu usaria como Interface IFuncionario e implementava nas outras duas! Se tiver código eu ai criaria um Abstração de Funcionario.
a melhor abordagem é aquela que resolve o seu problema.
faz sentido vc instanciar um Funcionario? não? então faz uma classe abstrata.
faz sentido vc usar uma Interface? tenta usar. se ficar complexo vc tira.
A melhor abordagem não é só que resolve seu problema, é a que está certa para um determinado problema, usar classes não é um trabalho fácil, muitas vezes se torna desafiador, classe abstract só usuaria se ela precisa ter codificação e Interface que vai servir de modelo, então no seu caso pode usar Interface!
eu simplifiquei.
existe casos onde vc pode ter tanto uma interface quanto uma classe abstrata. a minha experiencia me diz que uma interface emerge quando precisamos de um tipo de polimorfismo ( como o caso da List ).
uma ferramenta é usar Testes Unitarios. se o teste é complexo, então o modelo de classes certamente é complexo e pode ser refatorado. e as vezes na segunda ou terceira vez que estamos refatorando é possivel identificar comportamentos semelhantes e ai criar uma abstração melhor: que pode ser uma classe abstrata ou interface.
mas ai o desenvolvimento tem que ser continuo. e é um pouco mais dificil fazer o contrario: remover tipos inuteis e abstrações desnecessarias.
lembro de um dia que alguem ( com muito tempo livre, diga-se de passagem ) enfiou um monte de interfaces do tipo “read only” e “editavel” num projeto ai vc tinha 3 ou 4 interfaces pra cada classe e isso trazia Zero vantagem: por que quando vc queria algo “read only” na verdade vc queria era algo imutavel e pra isso vc não precisa de interface. nunca conseguimos tirar essa parada. e ai cada pessoa nova no projeto tinha que ler aquele mega comentario: POR FAVOR NAO REPITA ISSO.
Se eu peguei bem a sua ideia, neste caso você pode tratar isso com a classe abstrata informando tipos ENUM para os mesmos (Gerente e Diretor), caso venha surgir outro tipo de funcionário futuramente você só precisará acrescentar um novo tipo de ENUM (Novo Tipo Funcionário) na sua classe, acredito que isso já solucionaria o problema da maneira que você precisa.
Não consigo compreender:
a melhor abordagem é aquela que resolve o seu problema.
Isso que está detonando o mundo digital, se você simplificou, ao meu ver está errado, claro que tudo que é feito a mais está errado, mas ele perguntou qual melhor abordagem de um diagrama de classes, ao meu ver seria Implementação de uma Interface, ou até um herança simples de uma classe concreta, então tudo depende de um contexto maior, agora dizer que a melhor abordagem é a que resolver muitas vezes ela resolve e lá na frente ela ferra. Bom essa é minha opinião, respeito a sua!
O grande lance…é que eu não consigo ver vantagem na Interface e isso acredito ser uma limitação minha. É muito claro uma classe abstrata Funcionario e suas subclasses Diretor e Gerente. É muito claro que eles são funcionários mas precisam ser classificados em Diretor ou Gerente.
Se você fizer com interface, ela servirá de um modelo que pode ser implementado em outros momentos, se for abstract, além de servir como modelo, pode servir como código também ou seja, não existe elementos somente para implementar, existe código que pode ser reutilizado, mas, como eu digo, tudo vai depender.
Essa frase: O grande lance...é que eu não consigo ver vantagem na Interface e isso acredito ser uma limitação minha. se estiver pensando assim, tem que olhar para dentro das linguagens Orientadas a Objeto para você entender o porque nelas tem interface. O problema maior é como implementar e qual momento implementar, sendo assim um estudo, como já disse não é fácil fazer classe as pessoas acham que é faz e pronto ta certo.
Você pode experimentar as duas abordagens e ver qual é a melhor.
Se ele tiver que colocar 500 tipos de funcionários diferentes…
Acho que essa pergunta nos leva além do exemplo do amigo. O problema reside em: quando usar uma interface ou uma classe abstrata?
Pra mim a resposta não é clara, tudo vai do “depende”,do que você está vai precisar no futuro.
Para usar o polimorfismo, ambas são aceitáveis, o problema nasce onde elas divergem. Na própria api do Java o uso de Interfaces na api Collection e o uso de uma classe abstrata na api de IO (InputStream\OutputStream) não é por coincidência.
Pois é cara, loucura isso! Isso se vê mais em exemplos acadêmicos ou empresas de TI.
Usar o polimorfismo fica muito mais fácil, a longo prazo, do que ter um Enum com 500 opções.
Não sei se entendi, mas neste caso por outro lado não teriam 500 classes?
Por exemplo, vamos supor que para cada funcionário (não esquecer que são 500) tenha uma forma diferente de calcular o salário:
public void calculaSalario(Funcionario f){
if(f.getTipo()==Tipo1)`
//faz uma coisa
if(f.getTipo()==Tipo2)
//faz outra
...........
if(f.getTipo()==Tipo500)
//faz outra
Consegue imaginar 500 if’s aninhados? A chance de cometer um erro é mais que certa.
já, usando polimorfismo:
public void calculaSalario(Funcionario f){
f.calculaSalario();
}
Deixando o polimorfismo agir, seu trabalho vai ser implementar o método em cada classe, e não dentro de super método com vários if’s.
O trabalho de escrever você sempre terá, a questão é usar a Orientação a objetos e todos os seus recursos.
Esse “faz uma coisa”, “faz outra” podem ser tipos de regras definidos no banco de dados a cada tipo de funcionário, onde dependendo do caso o próprio administrador do módulo do sistema poderá definir isso. Melhor do que ter 500 classes, 500 enums ou 500 ifs. O trabalho deve ser orientado a funcionalidades.
por que você não usa herança, parece bem mais simples criar uma classe funcionário e especializar sub classes do tipo de funcionários a implementar;
Nesse exemplo simbólico é mais simples usar herança, não vejo trabalhando com polimorfismo, agora ai que mora o perigo, o que vai ser feito lá na frente que é o grande problema, falar de algo pontual é simples, falar de um sistema ou até de linguagens de programação ai sim a Orientação Objeto é bem complicada!
Se vocês olharem um pouco mais acima eu citei em uma resposta anterior que isso pode ser tratado de N maneiras, porém como ele citou que queria controlar somente GERENTE e DIRETOR, eu sugeri o ENUM, que é simples e rápido, mas conforme a abrangência da aplicação isso se torna uma prática inviável para uso!
@ERRO é exatamente essa a dúvida… quando usar Interface e quando usar Classe Abstrata. Ok, entendi que depende de cada situação e acredito que não terei essa resposta de forma clara… Eu entendi também… que se eu tiver um método calcularSalario… seria uma boa eu utilizar uma interface Funcionario e o funcionário que fosse passado…teria seu calculo da forma correta… blz…tbm entendi isso… Especificando bastante onde quero chegar, tenho o seguinte cenário:
Uma view (JSP), com um select onde seleciono o funcionario e submito o form e espero visualizar os dados do funcionário e seu salario calculado…
Um controller, onde recebo um funcionário somente com o ID e os outros atributos nulos.
Um Dao, onde recebo o funcionário só com o ID do controller, vou ao banco de dados, pego informações e preencho as informações restantes, devolvo pro Controller q vai devolver pra view…
O método calcularSalario deve estar no modelo? Digo, na Interface Funcionario em que o Gerente e o Diretor (ou os outros 500 tipos) vão implementar cada um da sua forma? Ou o meu controller deverá saber calcular o salario?
E se além de calcularSalario eu precisar ter calcularFerias, calcularVR, calcularVT, calcularHoraExtra, enviarEmailDeBoasVindas (que pode ser diferente por cargo…)… coloco todos na interface e todos os tipos de funcionários implementam da sua forma? Tipo… no controller… eu vou receber Funcionario só com o ID, o Dao vai preenchê-lo e devolverei para a view o resultado da implementação do método daquele funcionário?
Como o meu controller saberá qual funcionário vai receber? Já que virá apenas o ID preenchido?
@picklesdog70, seu Controller só deve fazer o meio de campo, receber a requisição e retornar a resposta, não deve saber como calcular salário.
A responsabilidade de calcular salário ficará em outro lugar dedicado a isso, dentro de um projeto que represente esse Negócio. Agora, o como fazer vai depender do que você tiver seguindo, pelo jeito é respeitando bem orientação a objetos, nessa parte não posso te ajudar muito.
Não acho que existe uma resposta clara pra isso tb, a principio você pode calcular o salário no banco quando for pegar as informações, no controller quando for montar a pagina, depende.
Dentro de algum objeto na sua estrutura de classes tb é possível, mas se esta usando OO nesse tipo de software orientado a CRUD na web, deve estar fazendo algo errado, ou mais complicado que necessário.
Por que resolveu usar OO nesse caso, vc pretende trabalhar em alguma consultoria Java?
Eu concordo com uma das opinioes acima de que a melhor abordagem é resolver o problema.
Há vários comentários discutindo soluçoes, mas pouco se pergunta sobre o problema em si.
O exemplo do calcula salário por exemplo, eu acho meio teórico: nao é um funcionário que determina seu próprio salário (exceto políticos). Especialmente para esse tipo de cargo, o salário geralmente é um valor arbitrário que você negociou quando foi contratado, é só mais um atributo de um funcionário, nao é comportamento.
Se a única diferença é essa, um atributo salário e um atributo cargo resolveria seu problema.
@AbelBueno é um exercicio… Mas o que está em jogo…é fazer da melhor forma possível… confesso a você que eu teria resolvido de alguma forma… mas eu quero fazer da melhor forma… quero fazer o certo e não só fazer…entregar e depois ver o q acontece e la resolve… 
Mas veja bem, você nao definiu um problema.
Disse que teria 3 classes: Funcionário, Gerente e Diretor. Só isso.
O que precisa fazer com essas classes? Qual o objetivo do exercício?
Nao existe melhor abordagem se nao existe um problema pra resolver.
Qualquer coisa que fizer será bom o bastante, pois nao é possível medir o resultado.
Você está certo. Faltaram detalhes.
Mas não tem um objetivo exato… eu estou estudando e criando situações hipotéticas… Estou criando um cenário onde alguem chegou pra mim e pediu: Quero um sistema que controle Diretores e Gerentes… e nessa empresa (que não existe) o salário de um Gerente é 3*<<SALARIO_QUE_ESTA_NO_BANCO>> e de um Diretor é 5*<<SALARIO_QUE_ESTA_NO_BANCO>>… (situações de exemplo…)…
Ai quero tentar imaginar, que amanha, surgiu o Coordenador…e agora o coordenador é 2*<<SALARIO_QUE_ESTA_NO_BANCO>>…
Ou seja… poderia inserir um montão de IF e resolver o problema… mas…será que é a melhor forma? Eu até acredito que em algum momento da vida…um montão de IFs possa ser uma solução… Mas exercitar a melhor forma de resolver uma situação, vejo como uma boa pratica!
Melhor não mexer com religião. São doutrinas que a religião prega como ideal, então vão seguir mesmo que seja exagero para atender bem a funcionalidade.
Ok, se você mesmo está criando estas situaçoes, sugiro que tente focar em problemas reais, regras de negócio reais, assim você tem algo pra resolver.
Nesse seu exemplo, o problema parece ser determinar o salário baseado no cargo de um funcionário.
E pelos seus exemplos, podemos generalizar que o salário é um fator, associado ao cargo, multiplicado por um valor base.
Note que nao há diferença de lógica entre cada cargo, só muda os dados (no caso o fator). Ou seja, nao precisa de interface ou herança, uma classe só dá conta disso. É a mesma lógica com diferentes parâmetros. E parâmetros você pode por em arquivos de configuraçao, banco de dados, Maps no código, etc.
Se você quer realmente pensar em lógicas diferente sendo aplicadas você pode pensar em calcular remuneraçao para funcionários (salário fixo), consultores (por hora trabalhada) e vendedores (salário base + comissao).
Isso provavelmente te daria um problema mais interessante pra resolver.
Foi mals pelo exemplo ruim…
Que isso, eu que peço desculpas se meu tom foi agressivo.
Você está tentando aprender boas práticas aqui e esse tipo de armadilha (pensar em soluçoes perfeitas e nao em resolver o problema) é muito comum na nossa área.
Tente encarar o que eu disse mas como uma crítica construtiva, nao como uma “bronca”. E continue perguntando, treinando, etc…é assim que se aprende!
Cria um app que resolve um problema real, ou um jogo; OO é bastante consolidado no front-end.
Quando tiver alguns anos de experiência, com uma bagagem maior, vc parte pro back-end.