Composição e herança são iguais? Se eu quiser implementar o padrão de composição, como posso fazer isso em Java?
java
oop
inheritance
composition
gmhk
fonte
fonte
Respostas:
Eles são absolutamente diferentes. A herança é um relacionamento "é-a" . A composição é um "tem-a" .
Você faz composição tendo uma instância de outra classe
C
como um campo da sua classe, em vez de se estendendoC
. Um bom exemplo de composição seria muito melhor do que a herançajava.util.Stack
, que atualmente se estendejava.util.Vector
. Agora isso é considerado um erro. Um vetor "is-NOT-a" da pilha ; você não deve inserir e remover elementos arbitrariamente. Deveria ter sido composição em seu lugar.Infelizmente, é tarde demais para corrigir esse erro de design, já que alterar a hierarquia de herança agora quebraria a compatibilidade com o código existente. Se havia
Stack
usado composição em vez de herança, sempre pode ser modificado para usar outra estrutura de dados sem violar a API .Eu recomendo o livro de Josh Bloch, Effective Java 2nd Edition
Um bom design orientado a objetos não se estende liberalmente às classes existentes. Seu primeiro instinto deve ser compor.
Veja também:
fonte
Composição significa
HAS A
Herança
IS A
Example
: O carro tem um motor e o carro é um automóvelNa programação, isso é representado como:
fonte
:-/
type
campo de TypeEnum
Como a herança pode ser perigosa?
Vamos dar um exemplo
1) Como está claro no código acima, a Classe Y possui um acoplamento muito forte com a classe X. Se algo mudar na superclasse X, Y poderá quebrar drasticamente. Suponha que, no futuro, a classe X implemente um método de trabalho com a assinatura abaixo
A alteração é feita na classe X, mas tornará a classe Y compilável. Portanto, esse tipo de dependência pode subir para qualquer nível e pode ser muito perigoso. Toda vez que a superclasse pode não ter total visibilidade para codificar dentro de todas as suas subclasses, a subclasse pode ficar observando o que está acontecendo na superclasse o tempo todo. Portanto, precisamos evitar esse acoplamento forte e desnecessário.
Como a composição resolve esse problema?
Vamos ver revisando o mesmo exemplo
Aqui, estamos criando referência da classe X na classe Y e invocando o método da classe X, criando uma instância da classe X. Agora todo esse forte acoplamento se foi. Superclasse e subclasse são altamente independentes uma da outra agora. As aulas podem fazer livremente alterações perigosas na situação de herança.
2) Segunda vantagem muito boa da composição, pois fornece flexibilidade de chamada de método, por exemplo:
Na classe Teste, usando a referência r, posso chamar métodos da classe X e da classe Y. Essa flexibilidade nunca esteve presente na herança
3) Outra grande vantagem: Teste de unidade
No exemplo acima, se o estado da instância x não for conhecido, ele poderá ser facilmente zombado usando alguns dados de teste e todos os métodos poderão ser facilmente testados. Isso não foi possível na herança, pois você dependia muito da superclasse para obter o estado da instância e executar qualquer método.
4) Outra boa razão pela qual devemos evitar a herança é que o Java não suporta herança múltipla.
Vamos dar um exemplo para entender isso:
Bom saber :
composição é facilmente alcançada em tempo de execução, enquanto a herança fornece seus recursos em tempo de compilação
composição também é conhecida como relação HAS-A e herança também é conhecida como relação IS-A
Portanto, crie o hábito de sempre preferir a composição à herança por várias razões acima.
fonte
A resposta dada por @Michael Rodrigues não está correta (peço desculpas; não posso comentar diretamente) e pode levar a alguma confusão.
A implementação de interface é uma forma de herança ... quando você implementa uma interface, não está apenas herdando todas as constantes, mas também comprometendo seu objeto com o tipo especificado pela interface; ainda é um " é-um relacionamento ". Se um carro implementa o Fillable , o carro " é-a " Fillable e pode ser usado em seu código onde quer que você use um Fillable .
A composição é fundamentalmente diferente da herança. Ao usar a composição, você está (como as outras respostas observam) fazendo um relacionamento " tem um " entre dois objetos, em oposição ao relacionamento " é um " que você cria ao usar a herança .
Portanto, a partir dos exemplos de carros nas outras perguntas, se eu quisesse dizer que um carro " tem um tanque de gasolina", usaria a composição da seguinte maneira:
Espero que isso esclareça qualquer mal-entendido.
fonte
A herança traz à tona a relação IS-A . Composição traz à tona a relação HAS-A . O padrão de estratégia explica que a composição deve ser usada nos casos em que há famílias de algoritmos que definem um comportamento específico.
Exemplo clássico de uma classe de pato que implementa um comportamento de vôo.
Assim, podemos ter várias classes que implementam o vôo, por exemplo:
Se fosse por herança, teríamos duas classes diferentes de pássaros que implementam a função de voar repetidamente. Portanto, herança e composição são completamente diferentes.
fonte
A composição é exatamente como parece - você cria um objeto conectando partes.
EDITAR o restante desta resposta é erroneamente baseado na seguinte premissa.
Isso é realizado com interfaces.
Por exemplo, usando o
Car
exemplo acima,Assim, com alguns componentes teóricos padrão, você pode construir seu objeto. É seu trabalho preencher como a
House
protege seus ocupantes e como aCar
protege seus ocupantes.A herança é como o contrário. Você começa com um objeto completo (ou semi-completo) e substitui ou substitui os vários bits que deseja alterar.
Por exemplo,
MotorVehicle
pode vir com umFuelable
método eDrive
método Você pode deixar o método Fuel como está, porque é o mesmo que encher uma moto e um carro, mas você pode substituir oDrive
método porque a Moto dirige de maneira muito diferente de aCar
.Com a herança, algumas classes já estão completamente implementadas e outras possuem métodos que você é forçado a substituir. Com a composição, nada é dado a você. (mas você pode implementar as interfaces chamando métodos em outras classes se houver algo por aí).
A composição é vista como mais flexível, porque se você tiver um método como iUsesFuel, poderá ter um método em outro lugar (outra classe, outro projeto) que se preocupe apenas em lidar com objetos que podem ser abastecidos, independentemente de se tratar de um carro, barco, fogão, churrasco, etc. As interfaces determinam que as classes que dizem que implementam essa interface tenham realmente os métodos que essa interface trata. Por exemplo,
então você pode ter um método em outro lugar
Exemplo estranho, mas mostra que esse método não se importa com o que está preenchendo, porque o objeto implementa
iUsesFuel
, pode ser preenchido. Fim da história.Se você usasse Herança em vez disso, precisaria de
FillHerUp
métodos diferentes para lidar com ,MotorVehicles
eBarbecues
, a menos que tenha algum objeto base "ObjectThatUsesFuel" bastante estranho do qual herdar.fonte
ThisCase
, não dentrocamelCase
. Portanto, é melhor nomear suas interfacesIDrivable
, etc. Você pode não precisar do "I" se reagrupar todas as suas interfaces em um pacote corretamente.Eles não são iguais.
Composição : Permite que um grupo de objetos seja tratado da mesma maneira que uma única instância de um objeto. A intenção de um composto é "compor" objetos em estruturas de árvore para representar hierarquias de partes inteiras
Herança : uma classe herda campos e métodos de todas as suas superclasses, sejam diretas ou indiretas. Uma subclasse pode substituir os métodos herdados ou pode ocultar campos ou métodos herdados.
O artigo da Wikipedia é bom o suficiente para implementar o padrão composto em java.
Principais Participantes:
Componente :
Folha :
Composto :
Exemplo de código para entender o padrão Composite :
resultado:
Explicação:
Consulte a pergunta abaixo para obter os prós e contras da composição e herança.
Prefere composição sobre herança?
fonte
como outro exemplo, considere uma classe de carro, isso seria um bom uso da composição, um carro "teria" um motor, uma transmissão, pneus, assentos etc. Não estenderia nenhuma dessas classes.
fonte
Composição é onde algo é composto de partes distintas e tem uma forte relação com essas partes. Se a parte principal morre, o mesmo ocorre com as outras, elas não podem ter vida própria. Um exemplo aproximado é o corpo humano. Retire o coração e todas as outras partes morrem.
A herança é onde você apenas pega algo que já existe e o usa. Não há um relacionamento forte. Uma pessoa pode herdar a propriedade de seu pai, mas pode ficar sem ela.
Como não conheço Java, não posso fornecer um exemplo, mas posso fornecer uma explicação dos conceitos.
fonte
A herança entre duas classes, onde uma classe estende outra classe, estabelece " IS A ".
A composição do outro lado contém uma instância de outra classe na sua classe e estabelece um relacionamento " Tem um ". A composição em java é útil, pois tecnicamente facilita a herança múltipla.
fonte
Na agregação simples de palavras, significa que possui um relacionamento.
A composição é um caso especial de agregação . De uma maneira mais específica, uma agregação restrita é chamada composição. Quando um objeto contém o outro objeto, se o objeto contido não puder existir sem a existência do objeto contêiner, ele será chamado de composição. Exemplo: Uma turma contém alunos. Um aluno não pode existir sem uma aula. Existe composição entre turma e alunos.
Por que usar agregação
Reutilização de código
Quando usar agregação
A reutilização de código também é melhor alcançada por agregação quando não há um navio de Relação
Herança
A herança é um relacionamento entre pais e filhos A herança significa que é um relacionamento
A herança em java é um mecanismo no qual um objeto adquire todas as propriedades e comportamentos do objeto pai.
Usando herança no Java 1 Code Reusability. 2 Adicione Recurso Extra na Classe Criança, bem como Substituição de Método (para que o polimorfismo em tempo de execução possa ser alcançado).
fonte
Embora Inheritance e Composition forneçam capacidade de reutilização de código, a principal diferença entre Composition e Herança em Java é que o Composition permite a reutilização de código sem estendê-lo, mas para Herança você deve estender a classe para qualquer reutilização de código ou funcionalidade. Outra diferença que resulta desse fato é que, ao usar o Composition, você pode reutilizar o código até para a classe final que não é extensível, mas a Herança não pode reutilizar o código nesses casos. Além disso, usando Composition, você pode reutilizar o código de muitas classes, pois elas são declaradas apenas como uma variável de membro, mas com o Herança, você pode reutilizar o formulário do código apenas uma classe, porque em Java você pode estender apenas uma classe, porque o recurso Herança múltipla não é suportado em Java. . Você pode fazer isso em C ++, porque uma classe pode estender mais de uma classe. BTW, você deve sempreprefiro Composition a Herança em Java , não sou apenas eu, mas até Joshua Bloch sugeriu em seu livro
fonte
Eu acho que este exemplo explica claramente as diferenças entre herança e composição .
Neste exemplo, o problema é resolvido usando herança e composição. O autor presta atenção ao fato de que; na herança , uma mudança na superclasse pode causar problemas na classe derivada, que a herdam.
Também é possível ver a diferença na representação quando você usa uma UML para herança ou composição.
http://www.javaworld.com/article/2076814/core-java/inheritance-versus-composition--which-one-should-you-choose-.html
fonte
Heranças versus Composição.
Heranças e composição são usadas para reutilização e extensão do comportamento da classe.
As heranças usadas principalmente em um modelo de programação de algoritmos de família, como o tipo de relação IS-A, significam tipos semelhantes de objetos. Exemplo.
Estes são pertencem à família Car.
A composição representa o tipo de relacionamento HAS-A. Mostra a capacidade de um objeto como o Duster tem cinco marchas, o Safari tem quatro marchas etc. Sempre que precisarmos estender a capacidade de uma classe existente, use a composição. Exemplo , precisamos adicionar mais uma engrenagem no objeto Duster, em seguida, precisamos criar mais um objeto de engrenagem e compor ao objeto Duster.
Não devemos fazer as alterações na classe base até / a menos que todas as classes derivadas precisem dessas funcionalidades. Nesse cenário, devemos usar Composition.Such
classe A Derivado pela classe B
Classe A Derivada pela Classe C
Classe A Derivada pela Classe D.
Quando adicionamos qualquer funcionalidade na classe A, ela fica disponível para todas as subclasses, mesmo quando as classes C e D não exigem essa funcionalidade. Para esse cenário, precisamos criar uma classe separada para essa funcionalidade e compor a classe necessária ( aqui é a classe B).
Abaixo está o exemplo:
fonte
Composição significa criar um objeto para uma classe que tenha relação com essa classe específica. Suponha que o aluno tenha relação com as contas;
Uma herança é que esta é a classe anterior com o recurso estendido. Isso significa que esta nova classe é a classe antiga com algum recurso estendido. Suponha que Aluno seja Aluno, mas Todos os Alunos são Humanos. Portanto, existe um relacionamento com aluno e humano. Isso é herança.
fonte
Não, ambos são diferentes. A composição segue o relacionamento "HAS-A" e a herança segue o relacionamento "IS-A". O melhor exemplo de composição foi o padrão estratégico.
fonte
Herança significa reutilizar a funcionalidade completa de uma classe. Aqui, minha classe precisa usar todos os métodos da superclasse e minha classe será totalmente acoplada à superclasse e o código será duplicado em ambas as classes em caso de herança.
Mas podemos superar todos esses problemas quando usamos a composição para conversar com outra classe. composição está declarando um atributo de outra classe na minha classe com a qual queremos conversar. e que funcionalidade queremos dessa classe que podemos obter usando esse atributo.
fonte