Diferença entre inheritance e composição

Composição e inheritance são as mesmas? Se eu quiser implementar o padrão de composição, como posso fazer isso em Java?

Eles são absolutamente diferentes. Herança é um relacionamento “é-um” . Composição é um “has-a” .

Você faz composição por ter uma instância de outra class C como um campo de sua class, em vez de estender C Um bom exemplo de composição que teria sido muito melhor que a inheritance é java.util.Stack , que atualmente estende java.util.Vector . Isso agora é considerado um erro. Um stack “is-NOT-a” vector; você não deve ter permissão para inserir e remover elementos arbitrariamente. Deveria ter sido composição em seu lugar.

Infelizmente é tarde demais para corrigir esse erro de projeto, já que alterar a hierarquia de inheritance agora quebraria a compatibilidade com o código existente. Se o Stack usasse composição em vez de inheritance, sempre poderia ser modificado para usar outra estrutura de dados sem violar a API .

Eu recomendo altamente o livro de Josh Bloch, Effective Java 2nd Edition

  • Item 16: Favorecer a composição sobre inheritance
  • Item 17: Projetar e documentar por inheritance ou proibi-la

Um bom design orientado a objects não é uma extensão generosa das classs existentes. Seu primeiro instinto deve ser compor em seu lugar.


Veja também:

  • Composição versus inheritance: uma análise comparativa de duas formas fundamentais de relacionar classs

Composição significa HAS A
Herança significa que IS A

Example : o carro tem um motor e o carro é um automóvel

Na programação isso é representado como:

 class Engine {} // The Engine class. class Automobile {} // Automobile class which is parent to Car class. class Car extends Automobile { // Car is an Automobile, so Car class extends Automobile class. private Engine engine; // Car has an Engine so, Car class has an instance of Engine class as its member. } 

Como a inheritance pode ser perigosa?

Vamos dar um exemplo

 public class X{ public void do(){ } } Public Class Y extends X{ public void work(){ do(); } } 

1) Como está claro no código acima, a Classe Y tem um acoplamento muito forte com a class X. Se algo mudar na superclass X, Y poderá quebrar drasticamente. Suponha que, no futuro, a class X implemente um método de trabalho com a assinatura abaixo

 public int work(){ } 

A mudança é feita na class X, mas tornará a class Y descompactável. ASSIM, esse tipo de dependência pode subir a qualquer nível e pode ser perigoso. Toda vez que a superclass pode não ter visibilidade total do código dentro de todas as suas subclasss, a subclass pode continuar percebendo o que está acontecendo na suerclass 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

 public class X{ public void do(){ } } Public Class Y{ X x=new X(); public void work(){ x.do(); } } 

Aqui estamos criando referência da class X na class Y e invocando o método da class X, criando uma instância da class X. Agora todo esse forte acoplamento se foi. Superclass e subclass são altamente independentes uma da outra agora. As classs podem fazer livremente mudanças que eram perigosas na situação de inheritance.

2) Segunda vantagem muito boa de composição em que fornece flexibilidade de chamada de método Por exemplo

 class X implements R {} class Y implements R {} public class Test{ R r; } 

Na class de teste usando r referência eu posso invocar methods de class X, bem como class Y. Essa flexibilidade nunca existiu em inheritance

3) Outra grande vantagem: teste unitário

 public class X{ public void do(){ } } Public Class Y{ X x=new X(); public void work(){ x.do(); } } 

No exemplo acima Se o estado da instância x não for conhecido, ela pode ser facilmente reproduzida usando alguns dados de teste e todos os methods podem ser facilmente testados. Isso não era possível na inheritance. Como você era altamente dependente da superclass para obter o estado de instância e executar qualquer método.

4) Outra boa razão pela qual devemos evitar a inheritance é que o Java não suporta múltiplas inheritances.

Vamos dar um exemplo para entender isso:

 Public class Transaction { Banking b; public static void main(String a[]) { b=new Deposit(); if(b.deposit()){ b=new Credit(); c.credit(); } } } 

Bom saber :

  1. composição é facilmente obtida em tempo de execução enquanto a inheritance fornece seus resources em tempo de compilation

  2. composição também é conhecida como relação HAS-A e inheritance também é conhecida como relação IS-A

Portanto, crie o hábito de sempre preferir a composição à inheritance por várias razões acima.

A resposta dada por @Michael Rodrigues não está correta (peço desculpas; não posso comentar diretamente), e poderia levar a alguma confusão.

Implementação de interface é uma forma de inheritance … quando você implementa uma interface, você não está apenas herdando todas as constantes, você está cometendo seu object para ser do tipo especificado pela interface; ainda é um relacionamento ” é-um “. Se um carro implementa Fillable , o carro ” é-umFillable e pode ser usado em seu código onde quer que você usasse um Fillable .

Composição é fundamentalmente diferente da inheritance. Quando você usa composição, você é (como as outras respostas notam) fazendo um relacionamento ” has-a ” entre dois objects, ao contrário do relacionamento ” é-um ” que você faz quando usa inheritance .

Então, a partir dos exemplos de carro nas outras perguntas, se eu quisesse dizer que um carro ” tem um ” tanque de gasolina, eu usaria composição, como segue:

 public class Car { private GasTank myCarsGasTank; } 

Espero que isso elimine qualquer mal-entendido.

A inheritance traz a relação IS-A . Composição traz relação HAS-A . O padrão Statergy explica que o Composition deve ser usado nos casos em que há famílias de algoritmos que definem um comportamento específico.
Exemplo clássico sendo de uma class de pato que implementa um comportamento de mosca.

 public interface Flyable{ public void fly(); } public class Duck { Flyable fly; public Duck(){ fly=new BackwardFlying(); } } 

Assim, podemos ter várias classs que implementam o vôo, por exemplo:

 public class BackwardFlying implements Flyable{ public void fly(){ Systemout.println("Flies backward "); } } public class FastFlying implements Flyable{ public void fly(){ Systemout.println("Flies 100 miles/sec"); } } 

Se fosse por inheritance, teríamos duas classs diferentes de aves que implementariam repetidamente a function voar. Assim, a inheritance e a composição são completamente diferentes.

Composição é o que parece – você cria um object conectando partes.

EDIT o resto desta resposta é erroneamente com base na seguinte premissa.
Isso é feito com interfaces.
Por exemplo, usando o exemplo do Car acima,

 Car implements iDrivable, iUsesFuel, iProtectsOccupants Motorbike implements iDrivable, iUsesFuel, iShortcutThroughTraffic House implements iProtectsOccupants Generator implements iUsesFuel 

Então, com alguns componentes teóricos padrão, você pode construir seu object. É então seu trabalho para preencher como uma House protege seus ocupantes e como um Car protege seus ocupantes.

A inheritance é como o contrário. Você começa com um object completo (ou semi-completo) e substitui ou substitui os vários bits que deseja alterar.

Por exemplo, o MotorVehicle pode vir com um método Fuelable e um método Drive . Você pode deixar o método de combustível como é porque é o mesmo para encher uma moto e um carro, mas você pode replace o método Drive , porque a moto dirige de forma muito diferente de um Car .

Com inheritance, algumas classs já estão completamente implementadas e outras possuem methods que você é forçado a sobrescrever. Com Composição nada é dado a você. (mas você pode implementar as interfaces chamando methods em outras classs se você tiver alguma coisa por perto).

A composição é vista como mais flexível, porque se você tiver um método como o iUsesFuel, você pode ter um método em outro lugar (outra class, outro projeto) que apenas se preocupa em lidar com objects que podem ser alimentados, independentemente de ser um carro, barco, fogão, churrasqueira, etc. Interfaces exigem que as classs que dizem implementar essa interface realmente tenham os methods de interface. Por exemplo,

 iFuelable Interface: void AddSomeFuel() void UseSomeFuel() int percentageFull() 

então você pode ter um método em outro lugar

 private void FillHerUp(iFuelable : objectToFill) { Do while (objectToFill.percentageFull() <= 100) { objectToFill.AddSomeFuel(); } 

Exemplo estranho, mas mostra que esse método não se importa com o que está sendo preenchido, pois o object implementa o iUsesFuel , ele pode ser preenchido. Fim da história.

Se você usasse Inheritance, você precisaria de diferentes methods FillHerUp para lidar com MotorVehicles e Barbecues , a menos que você tivesse um estranho object básico "ObjectThatUsesFuel" para herdar.

como outro exemplo, considere uma class de carro, isto seria um bom uso de composição, um carro teria “um” motor, uma transmissão, pneus, assentos, etc. Não estenderia nenhuma dessas classs.

Composição e inheritance são as mesmas?

Eles não são iguais.

Composição : Permite que um grupo de objects tenha que ser tratado da mesma maneira que uma única instância de um object. A intenção de um composto é “compor” objects em estruturas de tree para representar hierarquias de partes inteiras

Herança : Uma class herda campos e methods de todas as suas superclasss, sejam elas diretas ou indiretas. Uma subclass pode replace methods herdados ou pode ocultar campos ou methods herdados.

Se eu quiser implementar o padrão de composição, como posso fazer isso em Java?

Artigo da Wikipedia é bom o suficiente para implementar o padrão composto em java.

insira a descrição da imagem aqui

Principais participantes:

Componente :

  1. É a abstração para todos os componentes, incluindo os compostos
  2. Declara a interface para objects na composição

Folha :

  1. Representa objects folha na composição
  2. Implementa todos os methods de componente

Composto :

  1. Representa um componente composto (componente tendo filhos)
  2. Implementa methods para manipular crianças
  3. Implementa todos os methods de Componente, geralmente delegando-os a seus filhos

Exemplo de código para entender o padrão composto :

 import java.util.List; import java.util.ArrayList; interface Part{ public double getPrice(); public String getName(); } class Engine implements Part{ String name; double price; public Engine(String name,double price){ this.name = name; this.price = price; } public double getPrice(){ return price; } public String getName(){ return name; } } class Trunk implements Part{ String name; double price; public Trunk(String name,double price){ this.name = name; this.price = price; } public double getPrice(){ return price; } public String getName(){ return name; } } class Body implements Part{ String name; double price; public Body(String name,double price){ this.name = name; this.price = price; } public double getPrice(){ return price; } public String getName(){ return name; } } class Car implements Part{ List parts; String name; public Car(String name){ this.name = name; parts = new ArrayList(); } public void addPart(Part part){ parts.add(part); } public String getName(){ return name; } public String getPartNames(){ StringBuilder sb = new StringBuilder(); for ( Part part: parts){ sb.append(part.getName()).append(" "); } return sb.toString(); } public double getPrice(){ double price = 0; for ( Part part: parts){ price += part.getPrice(); } return price; } } public class CompositeDemo{ public static void main(String args[]){ Part engine = new Engine("DiselEngine",15000); Part trunk = new Trunk("Trunk",10000); Part body = new Body("Body",12000); Car car = new Car("Innova"); car.addPart(engine); car.addPart(trunk); car.addPart(body); double price = car.getPrice(); System.out.println("Car name:"+car.getName()); System.out.println("Car parts:"+car.getPartNames()); System.out.println("Car price:"+car.getPrice()); } } 

saída:

 Car name:Innova Car parts:DiselEngine Trunk Body Car price:37000.0 

Explicação:

  1. Parte é uma folha
  2. O carro contém muitas peças
  3. Diferentes partes do carro foram adicionadas ao carro
  4. O preço do carro = sum de (preço de cada parte )

Consulte a pergunta abaixo para Prós e Contras de Composição e Herança.

Prefere composição sobre inheritance?

A inheritance entre duas classs, em que uma class estende outra class, estabelece o relacionamento ” IS A “.

Composição na outra extremidade contém uma instância de outra class em sua class estabelece relação ” Has A “. Composição em java é útil, pois tecnicamente facilita a inheritance múltipla.

Em simples agregação de palavras significa que tem um relacionamento ..

Composição é um caso especial de agregação . De uma maneira mais específica, uma agregação restrita é chamada de composição. Quando um object contém o outro object, se o object contido não puder existir sem a existência do object contêiner, ele será chamado de composição. Exemplo: uma turma contém alunos. Um estudante não pode existir sem uma aula. Existe composição entre class 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á uma relação.

Herança

Herança é uma inheritance de relacionamento pai-filho Significa uma relação

A inheritance em java é um mecanismo no qual um object adquire todas as propriedades e comportamentos do object pai.

Usando inheritance em Reutilização de Código Java 1. 2 Adicione Extra Feature em Child Class assim como Overriding de Método (para que o polymorphism de tempo de execução possa ser alcançado).

Composição é onde algo é feito de partes distintas e tem um forte relacionamento com essas partes. Se a parte principal morre, os outros também não podem ter vida própria. Um exemplo grosseiro é o corpo humano. Retire o coração e todas as outras partes morrem.

Herança é onde você pega algo que já existe e usa. Não há relacionamento forte. Uma pessoa poderia herdar a propriedade de seu pai, mas ele pode ficar sem ela.

Eu não sei Java, então não posso fornecer um exemplo, mas posso fornecer uma explicação dos conceitos.

Embora Herança e Composição forneçam reutilização de código, a principal diferença entre Composição e Herança em Java é que Composição permite reutilizar código sem estendê-lo, mas para Herança você deve estender a class para qualquer reutilização de código ou funcionalidade. Outra diferença que vem desse fato é que, usando o Composition, você pode reutilizar o código para a class final, que não é extensível, mas a Herança não pode reutilizar o código em tais casos. Também usando Composição você pode reutilizar código de muitas classs pois elas são declaradas apenas como uma variável de membro, mas com Herança você pode reutilizar código de apenas uma class porque em Java você só pode estender uma class, porque múltiplas Heranças não são suportadas em Java . Você pode fazer isso em C ++, porque uma class pode estender mais de uma class. BTW, você deve sempre preferir composição sobre inheritance em Java , não é só eu, mas mesmo Joshua Bloch sugeriu em seu livro

Eu acho que este exemplo explica claramente as diferenças entre inheritance e composição .

Neste exemplo, o problema é resolvido usando inheritance e composição. O autor presta atenção ao fato de que; na inheritance , uma mudança na superclass pode causar problemas na class derivada, que a herdam.

Lá você também pode ver a diferença na representação quando usa uma UML para inheritance ou composição.

http://www.javaworld.com/article/2076814/core-java/inheritance-versus-composition–which-one-should-you-choose-.html

Heranças Vs Composição.

Heranças e composição são usadas para reutilização e extensão do comportamento de class.

Heranças, principalmente, usam em um modelo de programação de algoritmo familiar, como o tipo de relação IS-A, que significa um tipo similar de object. Exemplo.

  1. Duster é um carro
  2. Safari é um carro

Estes são da família Car.

Composição representa o tipo de relacionamento HAS-A.Ele mostra a capacidade de um object como o Duster tem Cinco Gears, o Safari tem quatro Gears, etc. Sempre que precisarmos estender a capacidade de uma class existente, use a composição. Exemplo , precisamos adicionar mais uma engrenagem no object Duster, então temos que criar mais um object de engrenagem e compor para o object duster.

Não devemos fazer as alterações na class base até / a menos que todas as classs derivadas precisem dessas funcionalidades. Para este cenário, devemos usar Composition.Such

class A Derivado pela Classe B

Classe A Derivado pela Classe C

Classe A Derivado pela Classe D.

Quando adicionamos qualquer funcionalidade na class A, ela fica disponível para todas as subclasss mesmo quando as Classes C e D não exigem essas funcionalidades. Para esse cenário, precisamos criar uma class separada para essas funcionalidades e compor para a class requerida ( aqui está a class B).

Abaixo está o exemplo:

  // This is a base class public abstract class Car { //Define prototype public abstract void color(); public void Gear() { Console.WriteLine("Car has a four Gear"); } } // Here is the use of inheritence // This Desire class have four gears. // But we need to add one more gear that is Neutral gear. public class Desire : Car { Neutral obj = null; public Desire() { // Here we are incorporating neutral gear(It is the use of composition). // Now this class would have five gear. obj = new Neutral(); obj.NeutralGear(); } public override void color() { Console.WriteLine("This is a white color car"); } } // This Safari class have four gears and it is not required the neutral // gear and hence we don't need to compose here. public class Safari :Car{ public Safari() { } public override void color() { Console.WriteLine("This is a red color car"); } } // This class represents the neutral gear and it would be used as a composition. public class Neutral { public void NeutralGear() { Console.WriteLine("This is a Neutral Gear"); } } 

Composição significa criar um object para uma class que tenha relação com essa class em particular. Suponha que o aluno tenha relação com contas;

Uma inheritance é, esta é a class anterior com o recurso estendido. Isso significa que essa nova class é a class Old com algum recurso estendido. Suponha que o aluno seja aluno, mas todos os alunos sejam humanos. Então, há um relacionamento com estudante e humano. Isso é inheritance.

Não, ambos são diferentes. A composição segue o relacionamento “HAS-A” e a inheritance segue o relacionamento “IS-A”. O melhor exemplo para composição foi o padrão estratégico.

Herança significa reutilizar a funcionalidade completa de uma class, aqui minha class tem que usar todos os methods da superclass e minha class será titulada juntamente com a superclass e o código será duplicado em ambas as classs em caso de inheritances.

Mas podemos superar todos esses problemas quando usamos composição para falar com outra class. composição está declarando um atributo de outra class em minha class para a qual queremos conversar. e qual a funcionalidade que queremos da class que podemos obter usando esse atributo.

Intereting Posts