Herança: utilizar ou não?

Pessoal, boa noite.

Sou iniciante em Java e tenho estudado fervorosamente essa linguagem, mas algo me gera dúvida, devo tentar extinguir completamente a herança e tentar utilizar apenas composição e interfaces?

Faço essa pergunta pois vejo comentários meio divididos, e apesar de saber que deveria me ater ao curso que estou fazendo, acabo indo procurar, o que pode dificultar um pouco já que vejo muitas opiniões divergentes do mesmo assunto.

Desde já, agradeço!

O ideal é você postar seu caso. Não coloque a tecnologia na frente da necessidade.

Entendo. Não tenho um caso, apenas surgiu essa dúvida, mas de fato, não posso colocar a tecnologia na frente da necessidade que possa vir a surgir. Obrigado!

Se você usar JFrame você já está usando herança, mas o seu conceito dependendo do que você aprendeu pode ser complicado, pois você vai conhecer métodos abstract, implement, extends, @Override, etc, cada um com sua função. Eu particularmente recomendo não querer pular etapas, aconselho se quer aprender mais rápido que um professor está ensinando, então adquira uma apostila, pode ser uma que tenha na internet, e siga os exemplos desde o começo e procure fazer pelo menos +5 programas diferentes com cada exemplo, assim fica mais fácil de realmente entender.

1 curtida

Vou tentar ilustrar isso tomando a liberdade de colocar na discussão um outro ponto bem crítico de quem começa a estudar OO: if bom é if morto!.
O que isso significa?
Significa que não devemos, dentro de OO, usar ifs de maneira indiscriminada.
Da mesma maneira, devemos ter parcimônia ao cogitar herança.
Não é melhor usar composição/agregação?
Não é melhor usar implementação?
Se você analisar o que precisa desenvolver e identificar que uma composição ou implementar uma interface é mais adequado, sempre opte por tais soluções.
A última alternativa é estender.
Logo, não devo estender JFrame?
Sim! Este é um exemplo de “if morto”.
Quando você constrói uma “janela” (JFrame), dificilmente terá a necessidade de modificar o código e excluir aquela janela.
Que é o mesmo que ocorre com o if morto, ele sempre será o mesmo dificilmente será alterado.
Ficou mais claro?

Falks, não vejo problema em usar herança nas classes, aqui onde trabalho tem alguns sistemas que realizam o uso, oque percebo que sempre que existe a necessidade de herdar comportamentos e atributos comuns, o pessoal usa, quando a necessidade é mais para o comportamento(método) das classes o pessoal usa interface, particulamente eu uso mais a composição, mas depende da necessidade e do nível de abstração a ser feito, tem um livro bacana para começar a se aprofundar é esse aqui, https://www.casadocodigo.com.br/products/livro-design-patterns
da uma olhada.

1 curtida

O objetivo da herança é justamente este: quando você modela e identifica que duas ou mais classes compartilham mesmas características (atributos) e operações (métodos), você cria uma classe que contemple os elementos comuns e, para cada elemento distinto, você cria subclasses da primeira.
Ou seja, você modela um elemento genérico (mais abrangente) e vai afunilando (especialização).
O grande problema, neste caso, é a questão do java limitar herança múltipla.
Por exemplo:
Você tem dois grandes reinos na natureza, o animal e o vegetal, certo? Podemos dizer que eles são classes.

public class Animal {}

public class Vegetal {}

Um elefante é um animal e uma laranja é um vegetal, fácil.
Também temos que existem seres que se alimentam de plantas, os herbívoros, e temos os que se alimentam de carne, os carnívoros.

Um elefante é herbívoro e um leão é carnívoro. Como você não pode ter herança múltipla, isso não pode ocorrer:

public class Carnivoro {}

public class Leao extends Animal, Carnivoro {} //herança múltipla, java não permite.

O que você faria? Óbvio:

public class Carnivoro extends Animal {}

public class Leao extends Carnivoro {}

Problema resolvido? Não!

Como você faria para representar a classe DioneaMuscipiladora, que é um Vegetal, mas é carnívora? Como você determinou que carnivoro é um animal, você não pode usar carnivoro para vegetais.
Percebe como a herança é limitadora? Ok, entendo que é um cenário hipotético e exagerado, mas, tem muita coisa assim no mundo do desenvolvimento.
Como resolver?
Transformar Carnivoro em uma interface

public interface Carnivoro {}

public class Leao extends Animal implements Carnivoro {}

public class DioneaMuscipiladora extends Vegetal implements Carnivoro {}

Agora sim. Mesmo que você identifique novos adjetivos para Leao ou DioneaMuscipiladora, você pode tratar cada um como sendo interfaces, permitindo que eles implementem isso.

public interface Mamifero {}

public class Leao extends Animal implements Mamifero, Carnivoro {}

Entendeu?

Ah, sim, é óbvio que você pode usar herança, mas, sempre se pergunte se não ficaria melhor com composição ou com implementação.

1 curtida

Obrigado pela dica de estudo, vou tentar utilizá-la

Perfeita explicação, é complicado ter informação na cabeça e não organizá-las. Me elucidou bastante, muito obrigado!

Não se desespere quanto a isso.
É comum que você encare problemas dessa ordem.