Devo usar herança ou composição? \| TreinaWeb               Promoção no ar   Matricule-se agora e garanta **54% de desconto**  

  Termina em   Tempo restante da oferta: 01 Horas 

 22 Min 

 37 Seg 

   Tempo restante da oferta: 01 22 37 

  [Assinar →](https://www.treinaweb.com.br/checkout/pagamento/plano/anual?cupom=TW-SCLIENTE26) 

   [                ](https://www.treinaweb.com.br)  Explorar  

 [ Quanto custa? ](#assinatura) [ FAQ ](https://www.treinaweb.com.br#faq) [Matricule-se](#assinatura) [ Entrar ](https://www.treinaweb.com.br/login) 

     [ Início ](https://www.treinaweb.com.br) [ Artigos ](https://www.treinaweb.com.br/blog) Devo usar herança ou composição?  [ Orientação a Objetos ](https://www.treinaweb.com.br/blog/categoria/orientacao-a-objetos) 

# Devo usar herança ou composição?

 A composição permite um reuso e extensão de código mais flexível que a herança clássica. Mas isso é motivo para sempre a escolhermos em detrimento à herança clássica?

 [ Kennedy Tedesco ](https://www.treinaweb.com.br/blog/autor/kennedy-tedesco) 10 anos atrás

  ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2021/05/87asgh12.png)  

Sempre que você vê `class {CLASS_NAME} extends {PARENT_CLASS_NAME}`, está diante de uma herança direta de classe, também conhecida como “herança clássica”, uma herança vertical onde as implementações e as especificações descem na “árvore”.

Um diagrama de um caso didático de herança:

![Diagrama de caso de herança](https://dkrn4sk0rn31v.cloudfront.net/2018/07/17114805/Screen-Shot-2017-05-02-at-19.32.00.png)

[  ![Java - Introdução à JPA](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/java.svg)   Curso Java - Introdução à JPA Conhecer o curso ](https://www.treinaweb.com.br/curso/java-introducao-jpa)

Se levado para um pseudo-código que usa o paradigma de [orientação a objetos](https://www.treinaweb.com.br/blog/os-pilares-da-orientacao-a-objetos/ "Os pilares da orientação a objetos"), poderíamos ter:

```php
class Animal
{
   // TODO
}

class Gato extends Animal
{
   // TODO
}

class Coelho extends Animal
{
   // TODO
}

class Cachorro extends Animal
{
   // TODO
}

```

A herança clássica nos leva as dois benefícios:

- **Reuso de contrato (especificação);**
- **Reuso de código (implementação);**

Se você já estudou orientação a objetos, em qualquer linguagem que seja, já deve ter “saturado” na mente a ideia de que a herança evita duplicação de código, uma vez que ela herda da classe pai suas partes concretas (implementações) e seus contratos/interfaces (especificações). No entanto, reuso de código por si só não é motivo para se usar herança. Reuso é **consequência** do uso de herança. Esse conceito é muito importante de se ter.

A herança faz sentido quando se tem a necessidade de representar um **tipo**, de tal forma que, quando essa classe é estendida, o seu **tipo** também é, podendo criar, inclusive, um novo **sub-tipo**.

No caso do nosso diagrama, temos a seguinte relação:

- *Animal* é a classe pai, o topo da hierarquia.
- *Gato* estende *Animal*, logo, *Gato* é do **tipo** Animal.
- *Cachorro* estende *Animal*, logo Cachorro **é** um *Animal* (só que mais específico);

Lidamos com uma inferência lógica: *Gato* estende *Animal*, logo, *Gato* também **é** um *Animal*.

Outra relação importante que temos na herança refere-se à **generalização** e à **especificação**. Quanto mais “alto” na árvore, mais genérico é, quanto mais baixo, mais específico. Generalizar é o ato de reunir características comuns numa classe de tal forma que ela possa servir de extensão para outras. No lado oposto, especificar é tornar específico, ou seja, com características mais singulares e que não devem estar na classe pai, pois, normalmente, são essas características que dão o valor de sub-tipo à classe em questão. A relação que temos é que, classes pai são classes de generalização e subclasses normalmente são classes de especialização.

Ainda dentro do nosso exemplo, a classe *Animal* deve ser, em teoria, a parte mais genérica e as subclasses *Gato*, *Coelho* e *Cachorro* devem ser mais específicas. Por exemplo, um método `latir()` não poderia estar na classe *Animal* para ser estendido para as outras, uma vez que essa é uma característica específica dos cachorros.

A herança clássica é um mecanismo útil e não deve ser demonizada. O grande problema é o seu mau uso, e se dá, normalmente, quando precisamos trazer características de outra classe para a nossa e, nesse caso, a primeira coisa que costuma vir à mente é a opção de “herdá-la” ao invés de pensarmos em objetos que comunicam entre sí.

Se a nossa classe não é do **tipo** da outra, herança não deve ser utilizada. Quando estendemos uma classe, não herdamos apenas a sua implementação e sua especificação, herdamos também o seu **tipo**. Logo, se uma classe não é do tipo da outra, a herança não é o mecanismo adequado.

É comum esse tipo de construção:

```php
class MySqlConnection
{
   // TODO
}

class Usuario extends MySqlConnection
{
  // TODO
}

```

![Exemplo usuário estende mysqlconnection](https://d2m498l008ebpa.cloudfront.net/2017/05/Screen-Shot-2017-05-15-at-20.00.40.png)

A classe `Usuario` estende a `MySqlConnection`. Mas, `Usuario` não é uma `MySqlConnection`, não é do tipo `MySqlConnection`. Esse tipo de erro é muito comum pois, como desenvolvedores, tendemos a achar que apenas a herança pode resolver os nossos problemas de reuso de código.

Esse exemplo, por sinal, é um caso para **composição**, de tal forma que saímos do contexto de **“ser”** para o contexto de **“usar”**. *Usuario* não deve **ser** *MySqlConnection*, ele precisa **usar** *MySqlConnection*.

Problemas que são evidenciados na super utilização de herança (em excesso):

- Mudar a classe pai pode afetar todas as classes filhas, mesmo quando isso não for intencional. O projeto fica um pouco menos previsível.
- O encapsulamento costuma ficar fraco (o acoplamento é forte, com uma tendo muito conhecimento sobre a outra, às vezes conhecimento até específico demais).
- A herança é um relacionamento estático, não é possível mudar em tempo de execução.

[  ![Kotlin com Android - Primeiros Passos](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/kotlin.svg)   Curso Kotlin com Android - Primeiros Passos Conhecer o curso ](https://www.treinaweb.com.br/curso/kotlin-com-android-primeiros-passos)

## Composição

Antes, um disclaimer: Nesse artigo, quando eu falo em composição, eu quero dizer: um objeto que **usa** outro objeto independentemente da relação associativa entre eles. Aqui é pouco importante separar a relação (se é uma agregação simples ou uma agregação de composição etc).

A composição também é uma forma de extensão, só que pela delegação de trabalho para outro objeto. Diferente da herança clássica onde tipo, atributos e métodos são estendidos. Quando uma classe precisa usar o **comportamento** de outra, usualmente é melhor usar composição.

Em termos gerais, se o seu problema não é caso para herança clássica, ele será um caso para composição (sem entrar aqui na possibilidade de se usar traits, um mecanismo de herança horizontal disponível em algumas linguagens).

Alguns dos pontos positivos do uso de composição:

- Facilita a mudança da associação entre classes em tempo de execução;
- Permite que um objeto assuma múltiplos comportamentos com decisões em tempo de execução;

Voltando ao nosso exemplo, a melhor relação que podemos ter:

![diagrama com o exemplo usuário usa mysqlconnection](https://d2m498l008ebpa.cloudfront.net/2017/05/Screen-Shot-2017-05-15-at-20.01.09.png)

E, traduzindo para código, poderíamos ter essa implementação:

```php
class MySqlConnection
{
   // TODO
}

class Usuario
{
	public function findById(int $id) : array
	{
		$connection = new MySqlConnection();

		// TODO
	}
}

```

*Usuario* não mais estende *MySqlConnection*, ao invés disso, ele instancia essa classe e utiliza o objeto resultante.

Mas, priorizando injeção de dependência e o princípio de inversão de dependência, a melhor alternativa seria construimos esse exemplo assim:

```php
class MySqlConnection implements Connection
{
   // TODO
}

class Usuario
{
    protected $connection;

    public function __construct(Connection $connection)
    {
        $this->connection = $connection;
    }

	public function findById(int $id)
	{
        $this->connection->select('...');

		// TODO
	}
}

$connection = new MySqlConnection();
$myUser = new Usuario($connection);

```

Assim como no primeiro exemplo, nesse também temos composição (no sentido de um objeto A que usa um objeto B). Só mudamos a forma deles se relacionarem. No primeiro exemplo temos uma associação de agregação de composição e nesse, injetamos *MySqlConnection* como dependência de *Usuario*, numa associação de agregação (onde a parte - *MySqlConnection* - não depende do todo - *Usuario* - para existir).

## Concluindo

Não faz sentido polarizar e afirmar que você deve usar uma em detrimento a outra. Composição e herança podem coexistir cada qual com seu caso de uso. Por outro lado, o uso de composição é sempre encorajado. Não exatamente no sentido de fazer o desenvolvedor “parar” de usar herança, mas no sentido de que, tendo mais objetos inter-relacionados (não no sentido de quantidade, mas no de qualidade de comportamento), as responsabilidades são melhores delegadas, favorece o reuso, a refatoração, a testabilidade e até mesmo a mudança de associação em tempo de execução.

Muitos objetos dificultam o relacionamento e até mesmo o gerenciamento deles como dependências e o código fica bem menos estático (menos previsível). No entanto, há mecanismos que nos ajudam bastante na resolução desses problemas, recomendo a leitura dos seguintes artigos:

- [Entendendo injeção de dependência](https://www.treinaweb.com.br/blog/entendendo-injecao-de-dependencia/)
- [Container de injeção de dependência (DI Container)](https://www.treinaweb.com.br/blog/container-de-injecao-de-dependencia-di-container/)

Um abraço!

[  ![Desenvolvedor PHP](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/php.svg)   Formação Desenvolvedor PHP Conhecer a formação ](https://www.treinaweb.com.br/formacao/desenvolvedor-php)

- [ #Orientação a objetos ](https://www.treinaweb.com.br/blog/tag/orientacao-a-objetos)
- [ #Desenvolvimento ](https://www.treinaweb.com.br/blog/tag/desenvolvimento)

Autor

 ![Kennedy Tedesco](//secure.gravatar.com/avatar/236c86e9469327ba7a9250ff15fef424?d=mm)

## Kennedy Tedesco

 Head de desenvolvimento. Vasta experiência em desenvolvimento Web com foco em PHP. Graduado em Sistemas de Informação. Pós-graduando em Arquitetura de Software Distribuído pela PUC Minas. Zend Certified Engineer (ZCE) e Coffee Addicted Person (CAP). [@KennedyTedesco](https://twitter.com/KennedyTedesco) 

 [Todos os artigos](https://www.treinaweb.com.br/blog/autor/kennedy-tedesco)  

## Continue estudando

 Transforme leitura em prática com os cursos e formações da TreinaWeb.

 [Ver cursos](https://www.treinaweb.com.br/cursos)   

  Continue lendo

## Artigos relacionados

- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2018/07/24104425/heranca-python-400x280.png)  [ Python ](https://www.treinaweb.com.br/blog/categoria/python) 

     8 anos atrás

    ##  [ Utilizando herança no Python ](https://www.treinaweb.com.br/blog/utilizando-heranca-no-python) 

     Veja na prática como usar herança no Python.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/04/01155343/traits-php-400x280.jpg)  [ PHP ](https://www.treinaweb.com.br/blog/categoria/php) 

     8 anos atrás

    ##  [ O que são Traits no PHP e quando usar? ](https://www.treinaweb.com.br/blog/quando-usar-traits-no-php) 

     Uma reflexão sobre reuso de código, herança e a recomendação de utilização de Traits.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2022/05/como-instalar-o-csharp-e-nosso-primeiro-exemplo-400x280.png)  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) 

     5 anos atrás

    ##  [ Como instalar o C# e nosso primeiro exemplo ](https://www.treinaweb.com.br/blog/como-instalar-o-csharp-e-nosso-primeiro-exemplo) 

     Neste artigo veremos como instalar o C# nos sistemas Windows, Linux e MacOS e também veremos como escrever nosso primeiro programa.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2022/07/DART-ORIENTACAO-OBJETOS-400x280.png)  [ Dart ](https://www.treinaweb.com.br/blog/categoria/dart) 

     4 anos atrás

    ##  [ Orientação a objetos em Dart ](https://www.treinaweb.com.br/blog/orientacao-a-objetos-em-dart) 

     Aprenda Orientação a objetos em Dart e como trabalhar com classes, atributos, métodos e objetos em Dart e aumente seus conhecimentos!

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2022/05/como-instalar-o-csharp-e-nosso-primeiro-exemplo-400x280.png)  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) 

     4 anos atrás

    ##  [ Orientação a objetos no C# ](https://www.treinaweb.com.br/blog/orientacao-a-objetos-no-csharp) 

     Aprenda como trabalhar com classes, atributos, métodos e objetos no C# e aumente seus conhecimentos nessa linguagem incrível!

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2018/12/16065017/front-back-ou-fullstack-400x280.png)  [ Carreira ](https://www.treinaweb.com.br/blog/categoria/carreira) 

     8 anos atrás

    ##  [ Devo começar como Front-End, Back-End ou Full Stack? ](https://www.treinaweb.com.br/blog/devo-comecar-como-front-end-back-end-ou-full-stack) 

     Devo começar minha carreira como desenvolvedor Front-End, Back-End ou FullStack?

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2018/08/10160857/capa-faculdade-x-curso-400x280.jpg)  [ Estudos ](https://www.treinaweb.com.br/blog/categoria/estudos) 

     8 anos atrás

    ##  [ Devo fazer uma faculdade ou um curso de especialização? ](https://www.treinaweb.com.br/blog/devo-fazer-uma-faculdade-ou-um-curso-de-especializacao) 

     Está na dúvida se deve fazer uma faculdade ou ir para os cursos de especialização? Esse artigo poderá te ajudar a decidir.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2017/11/13144813/devo-transformar-meu-site-em-uma-pwa-400x280.jpg)  [ Desenvolvimento Front-end ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento-front-end) 

     9 anos atrás

    ##  [ Devo transformar meu site em uma PWA? ](https://www.treinaweb.com.br/blog/devo-transformar-meu-site-em-uma-pwa) 

     Você sabe o que é uma PWA? Será que vale a pena transformar o seu site em uma?

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/01/07093212/PYTHON-400x280.png)  [ Desenvolvimento Back-end ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento-back-end) 

     7 anos atrás

    ##  [ Afinal, por que devo aprender Python para 2020? ](https://www.treinaweb.com.br/blog/afinal-por-que-devo-aprender-python-para-2020) 

     Veja neste artigo os motivos para aprender Python neste ano de 2020.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/06/28131344/capa-cloud-400x280.png)  [ Computação em nuvem ](https://www.treinaweb.com.br/blog/categoria/computacao-em-nuvem) 

     8 anos atrás

    ##  [ Por que eu devo estudar Cloud Computing? ](https://www.treinaweb.com.br/blog/por-que-eu-devo-estudar-cloud-computing) 

     Confira neste artigo alguns motivos que nos mostram o porquê de valer a pena aventurar-se nessa área.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2018/08/17135558/capa-marketing-digital1-400x280.jpg)  [ Marketing Digital ](https://www.treinaweb.com.br/blog/categoria/marketing-digital) 

     8 anos atrás

    ##  [ Por que devo investir no Marketing Digital? ](https://www.treinaweb.com.br/blog/por-que-devo-investir-no-marketing-digital) 

     Veja neste artigo o porquê você deve investir em Marketing Digital no seu negócio.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2018/02/09112204/capa-marketing-400x280.png)  [ Marketing Digital ](https://www.treinaweb.com.br/blog/categoria/marketing-digital) 

     9 anos atrás

    ##  [ Redes sociais: quais devo escolher para a minha empresa? ](https://www.treinaweb.com.br/blog/redes-sociais-quais-devo-escolher-para-a-minha-empresa) 

     Separamos as cinco principais redes sociais do momento e destacamos os pontos fortes de cada uma delas e sobre como podem ser úteis para o seu negócio.

     Ler artigo

## Um ano de acesso total para você viver de programação.

 Todos os cursos e formações da TreinaWeb numa única assinatura, com professores que atuam no mercado, suporte direto e certificados. Do primeiro `console.log` ao mercado de trabalho.

- **1 ano** de acesso a **todos os cursos**
- Cursos novos **toda semana**
- Suporte **direto com professores**
- Plano de carreira **personalizado**
- **Certificados digitais** inclusos
- **Aplicativos** para Android e iOS, com **acesso offline**

    **Garantia incondicional de satisfação** 

 Teste por 7 dias e, se não fizer sentido para você, devolvemos seu dinheiro.

### Acesso completo a todos os cursos e dezenas de Formações.

 12 meses 

  Economize R$ 840,00  54% OFF 

 de 12x R$ 129,00 por apenas

 12x  R$ 59,00

 sem juros no cartão de crédito ou R$ 599,00 à vista

  Oferta termina em  **01h 22min 37s**

- Acesso imediato e ilimitado durante 1 ano.
- Plano de carreira personalizado.
- Suporte direto com professores.
- E muito mais!

 [Matricule-se agora](https://www.treinaweb.com.br/checkout/pagamento/plano/anual?cupom=TW-SCLIENTE26)

     [                ](https://www.treinaweb.com.br)

 Escola online de programação, tecnologia e IA.

- [  ](https://www.facebook.com/TreinaWeb/)
- [  ](https://www.instagram.com/treinaweb/)
- [  ](https://www.youtube.com/user/TreinaWeb)
- [  ](https://twitter.com/treinaweb)
- [  ](https://www.linkedin.com/company/treinaweb)
- [  ](https://github.com/treinaweb)

## Inscreva-se em nossa newsletter

Receba lançamentos, promoções e novidades.

   Seu nome     Seu WhatsApp     Seu melhor e-mail   Inscrever-se 

## Cursos

- [ Base para Devs ](https://www.treinaweb.com.br/categoria/base-para-devs)
- [ Front-end ](https://www.treinaweb.com.br/categoria/desenvolvimento-front-end)
- [ Back-end ](https://www.treinaweb.com.br/categoria/desenvolvimento-back-end)
- [ Mobile ](https://www.treinaweb.com.br/categoria/desenvolvimento-mobile)
- [ Bancos de Dados ](https://www.treinaweb.com.br/categoria/bancos-de-dados)
- [ Cloud ](https://www.treinaweb.com.br/categoria/cloud-computing)
- [ IA ](https://www.treinaweb.com.br/categoria/ia)
- [ E mais ](https://www.treinaweb.com.br/categoria/e-mais)
- [ Ver todos os cursos ](https://www.treinaweb.com.br/cursos)

## Conteúdo

- [ Formações ](https://www.treinaweb.com.br/formacoes)
- [ Projetos práticos ](https://www.treinaweb.com.br/projetos-praticos)
- [ Direto ao ponto ](https://www.treinaweb.com.br/direto-ao-ponto)
- [ Planos ](https://www.treinaweb.com.br#assinatura)
- [ Depoimentos ](https://www.treinaweb.com.br#depoimentos)
- [ Comunidade ](https://www.treinaweb.com.br#comunidade)
- [ Corpo docente ](https://www.treinaweb.com.br#docente)

## A empresa

- [ Sobre a TreinaWeb ](https://www.treinaweb.com.br#sobre)
- [ Perguntas frequentes ](https://www.treinaweb.com.br#faq)
- [ Vantagens de estudar na TreinaWeb ](https://www.treinaweb.com.br/vantagens-de-estudar-na-treinaweb)
- [ Cursos para empresas ](https://www.treinaweb.com.br/empresas)
- [ Sugira um novo curso ](https://www.treinaweb.com.br/sugerir-curso)
- [ Trabalhe conosco ](https://www.treinaweb.com.br/trabalhe-conosco)
- [ Artigos ](https://www.treinaweb.com.br/blog)
- [ Desenvolvedores e agentes ](https://www.treinaweb.com.br/developers)
- [ Contato ](https://www.treinaweb.com.br/contato)
- [ Política de privacidade ](https://www.treinaweb.com.br/politica-de-privacidade)
- [ Termos de uso ](https://www.treinaweb.com.br/termos-de-uso)

## Baixe nosso aplicativo

 [   Disponível na **App Store**  ](https://apps.apple.com/us/app/treinaweb/id1322729447) [   Disponível no **Google Play**  ](https://play.google.com/store/apps/details?id=br.com.treinaweb.mobile) 

  Av. Paulista, 1765, Conj 71 e 72 · Bela Vista · São Paulo · SP · 01311-200   © 2004 – 2026 TreinaWeb Tecnologia LTDA · CNPJ 06.156.637/0001-58
