Olá pessoal do guj, sou iniciante em java e gostaria de saber quando devo usar herança e quando devo favorecer a composiçao. Eu sei que a composiçao torna meu sistema mais flexível e permite escolher objetos em tempo de execuçao, porém com a herança eue posso reaproveitar código, porém eu fico preso a um hierarquia de classes, entao pessoal devo usar herança quando as subclasses realmente são um subtipo de da classe mãe?
Favorecimento da composiçao sobre a herança
17 Respostas
Carinha, o que eu tenho visto é que no desenvolvimento o pessoal acaba usando as duas coisas: composição para expor uma API publicamente e herança para gerar uma implementação padrão da API. O projeto eclipse faz isto o tempo todo: eles especificam interfaces para acoplar todos os plugins que eles fazem, e fazem uma implementação padrão, abstrata, dessas interfaces. Aí a pessoa pode simplesmente aplicar herança para gerar sua classe específica, ou até reimplementar a interface toda do nada…
Amigo. Estava dando uma procurada e encontrei a explicação de outro colega que foi muito boa. Segue abaixo:
Em primeiro lugar Herança e Composição são dois mecanimos utilizados para reutilizar funcionalidades.
Até hj alguns programadores acham q herança é o q há no mundo!!! Mas na verdade composição é muito mais superior.
Na Herança, as classes estendem métodos e atributos da classe Pai (Mãe, Superclasse ou como queira chamar), já a composição estende uma classe pela delegação de trabalho para outro objeto.
Um exemplo de composição: um controle de domínios de uma empresa!! Uma empresa “tem um” endereço. Podemos deixar o objeto empresa responsável pelo objeto endereço e temos aí uma agregação composta ou em outras palavras composição.
Herança é quando classes possuem atributos e métodos em comum. Esses métodos e atributos em comum vão para a superclasse. Um exemplo é um sistema de uma empresa onde é realizado um cadastro de funcionários. Podemos criar uma classe Funcionário com seus métodos e atributos. Mas devemos pensar q uma Secretária, um Diretor, um Gerente são Funcionários.
Acho q fica mais claro diferencia um do outro da seguinte forma: na Composição um objeto “tem outro”. E já na Herança uma classe “é” outra (Diretor é um Funcionário).
acho que entendi, pelo que vocês afirmaram eu devo usar herança com cuidado, procurar programar para uma interface e usar composição. Mas o uso de herança e de composiçao vai depender mais do domínio ? estou certo?
Ah e desde já obrigado
Sem querer abusar demais alguém conhece alguma ferramenta modelagem uml para linux que seja boa? Pelo que pude perceber pelas respostas de vocês o uso desses recursos dependem muito do dominio entao acho que vou procurar modelar mais minhas classes antes de programar
Voce deve pensar no conceito Is-One x Has-one
Manager ‘is-one’ Person.
Builder ‘has-one’ address.
Só tome cuidado na hora de implementar suas classes com Herança , li um artigo essa semana de um amigo aqui do GUJ (infelizmente não lembro o nome nem o site) sei que o cara trampa na Ilegria em RS algo assim , e o post dizia:
Ou pior aplicando o conceito acima Company (Pessoa Juridica) is-one Person?
Cuidado com o que se aprende na faculdade , e sempre que utilizar um recurso de OO pergunte-se se aquilo realmente é necessário e porquê você está fazendo isso ou aquilo . Composição , Herança , Polimorfismo Porque vou usar ou não usar?
Feijão com Arroz que todo estudante que sonha em ser desenvolvedor um dia tem que saber .
Boa sorte com teus estudos .
E Lembre-se sempre desenvolva um raciocínio critico perante as coisas , nem tudo que alguém te ensinou as vezes é a melhor maneira de ser feita.
Realmente é verdade a faculdade só joga os conceitos sem mostrar seus pontos fortes e pontos fracos. Nesse caso que vc citou acima sobre a empresa ser irma de um ser humano é inadequado usar herança mesmo, porque seria absurdo isso, o problema da herança é que se os requisitos mudam a gente corre o risco de implementar coisas sem sentido e acabamos presos na hierarquia de classes, mas a questão de usá-la esta ligada mesmo ao dominio? certo?
Ah e obrigado pelos conselhos, programar é bom, mas pelo que vejo ser bom programador exige muito estudo. Valeu pelas dicas kara
Assim não vale, esses exemplos são um pouco tendenciosos hehe
Pessoa Jurídica é uma Pessoa? A resposta é: depende
É possível ter a palavra “Pessoa” em dois sentidos, uma pessoa de verdade (ser humano) ou uma pessoa no sentido civil,tributário,juridico,etc.
No primeiro sentido, é óbvio que uma empresa não é uma pessoa.
No segundo sentido, uma pessoa física e uma pessoa jurídica são a mesma coisa! um “ser” que faz parte da sociedade e tem direitos e deveres.
Então tudo depende do negócio que se está modelando, o que significa uma Pessoa no contexto.
Por exemplo, trabalhei em algumas instituições financeiras e em suas bases de dados Pessoa Física e Pessoa Jurídica sempre eram consideradas especializações (subclasses) de Pessoa; isso porque nesse contexto um cliente físico ou jurídico representam basicamente o mesmo.
E sobre esse negócio de “irmão”: não caia nesse argumento, é puro jogo de palavras! é como afirmar o seguinte: "Gato e Cachorro podem extends de Animal, certo? Então quer dizer que um Gato pode ser Irmão de um Cachorro? "
Company (Pessoa Juridica) is-one Person ?
Nesse caso é mais um problema de tradução entre os idiomas. Acredito que em inglês Person não sirva para designar uma entidade jurídica, mas em português existe esse significado (http://www.dicionarioweb.com.br/pessoa.html). A tradução literal acaba atrapalhando os conceitos.
OBS: Não estou defendendo uso exagerado da herança não hein 
É só uma pequena correção, mas fora isso seus conselhos foram totalmente pertinentes, o importante é analisar criticamente cada situação e escolher o recurso mais adequado
Por exemplo, trabalhei em algumas instituições financeiras e em suas bases de dados Pessoa Física e Pessoa Jurídica sempre eram consideradas especializações (subclasses) de Pessoa; isso porque nesse contexto um cliente físico ou jurídico representam basicamente o mesmo.
Até concordo que em alguns pontos isso pode ser considerado , agora analise :
É correto que o Funcionário que não deixa de ser uma Pessoa extender a mesma classe que uma Pessoa Jurídica?
Eu acho muito mais elegante ter uma classe DadosCadastrais .
Prefira a composição!
Como eu resolveria o problema da PessoaFisica e PessoaJuridica? Simples, usando composição. Vamos supor que você estivesse usando a classe Pessoa apenas para reutilizar dados cadastrais, ótimo, crie a classe DadosCadastrais e faça ela compor todas as classes que utilizem estes dados.
Quando usar herança?
Quando você definitivamente está certo que sua classe é uma especialização de alguma outra classe, que BEM PROVAVELMENTE será provida via polimorfismo. Por exemplo: ControleRemotoUniversal extends ControleRemoto.
A reutilização de código acontece uma vez que você ganha a componentização, onde você transformará sua família de objetos em um componente que se comunica muito bem com os objetos internos e externos. Isso é reutilizar código.
Até intendi oque voce quis dizer , e também intendi o exemplo que demonstrou no projeto que trabalhou ,mas mesmo assim fiquei com um pé atras se isso poderia ser feito em qualquer projeto , oque pode acontecer se o programador não souber oque está fazendo direito e dizer:
Vou fazer assim porque naquele projeto nós fizemos e ficou muito bom…
E sobre esse negócio de “irmão”: não caia nesse argumento, é puro jogo de palavras! é como afirmar o seguinte: "Gato e Cachorro podem extends de Animal, certo? Então quer dizer que um Gato pode ser Irmão de um Cachorro? "
Oque quis dizer é que intendo como Herança que deve haver uma especialização da classe Pai e que uma empresa nunca podera ser uma especialização de Pessoa.
Já qualquer animal como gato , cachorro não deixa de ser uma especialização da classe pai Animal.
Foi isso que quis dizer , posso ter me expressado mal , só quis alertar com o cuidado na condição É-UM … que pode trazer muita dor de cabeça
Quando você definitivamente está certo que sua classe é uma especialização de alguma outra classe, que BEM PROVAVELMENTE será provida via polimorfismo. Por exemplo: ControleRemotoUniversal extends ControleRemoto.
A reutilização de código acontece uma vez que você ganha a componentização, onde você transformará sua família de objetos em um componente que se comunica muito bem com os objetos internos e externos. Isso é reutilizar código.
Acho que isso resume bem a questão.
E apesar de ter discutido sua colocação, dificilmente eu implementaria um modelo usando herança. Foi só pra ser chato mesmo hehe
Muito bom o post, nunca tinha visto alguém questionar a respeito do conceito “é um”, agora entendi e não “intendi” o conceito.
Bom, seria interessante editar o post e retirar o “intendi”, por favor não me interpretem mal…
gomesrod
Como eu disse , posso ter me expressado mal , porem é bom essas discussões sadias pois muitas pessoas eu mesmo achava que sabia OO até que cai em uma situação dessa , oque eu quis foi despertar o autoconhecer de saber o porque das coisas acontecem , acredite muita gente parece um robo programando vai produzindo linhas e linhas de códigos como se fosse uma maquina .
Acredito que esta profissão se iguala mais a de um artesão que pensa nos mínimos detalhes do que um processo de fabricação.
E só uma coisa , eu ainda não sou Programador Java também wolfx0 igual a você , mas pense o seguinte quando se aprende certo , dificilmente irá se conformar em POG’s que ve por ai , e o melhor de tudo irá saber diferenciar oque é certo , do que não é.
É como o amigo gomesrod citou tem casos e casos , o bom é saber mesmo quando e como agir.
Sem querer abusar demais alguém conhece alguma ferramenta modelagem uml para linux que seja boa? Pelo que pude perceber pelas respostas de vocês o uso desses recursos dependem muito do dominio entao acho que vou procurar modelar mais minhas classes antes de programar
Eu uso o Violet UML Editor, procura ai no google. É simples e para iniciantes, veja se serve para você.
Sobre composição versus herança, tem esse ótimo artigo do Bill Venners, publicado em 98 na Java World:
http://www.artima.com/designtechniques/compoinh.html
E, claro, não dá para faltar também artigo com o Erich Gamma (um dos autores do livro de Design Patterns, criador do JUnit e do Eclipse), que foi entrevistado justamente pelo Bill Venners (autor do artigo de cima):
http://www.artima.com/lejava/articles/designprinciples4.html
Valeu Lucas pela informaçao, eu irei baixar para testar
Mais uma vez obrigado pessoal pelo apoio sobre a duvida entre composiçao e herança