Introdução a Orientação a Objetos
Tags: beginners, oop, backend
Published: 2024-02-18 20:06:30

## Sumário

1. [O que é Orientação a Objetos](#1-o-que-é-orientação-a-objetos)
2. [Classes](#2-classes)
   - [Campos](#21-campos)
   - [Construtor](#22-construtor)
   - [Métodos](#23-métodos)
3. [Hierarquia das Classes](#3-hierarquia-das-classes)
   - [Superclasse e Subclasses](#31-superclasse-e-subclasses)
   - [Subclasses e Sub-subclasses](#32-subclasses-e-sub-subclasses)
4. [Interfaces](#4-interfaces)

---

### 1. O que é <a name="1-o-que-é-orientação-a-objetos">

Orientação a objetos é um paradigma da programação, tem como base a criação de classes e a forma como essas classes se relacionam, ajudando na organização, reutilização e diminuindo a reescrita de código, a seguir vou falar mais sobre as classes e como podemos trabalhar com elas.

### 2. Classes <a name="2-classes">

Uma classe é a base para a criação de um objeto, podemos compara-la a uma receita de bolo, nela vamos definir o que deve ser construído, como deve ser construído e quais suas características. A anatomia da classe é composta por três itens:

#### 2.1. Campos <a name="21-campos">

São características/atributos padrões que a classe possui.

Ex. Imagine um **Post** em um blog, quais seriam seus atributos? Podemos imaginar algo como: **titulo**, **data de criação**, **autor**, **conteúdo** e por ai vai. **Post** é a nossa **classe** e os atributos que listamos anteriormente são os **campos** da classe.

Estes campos podem ter diferentes tipos de acesso. Podem ser **públicos** (Acessados por qualquer um), **privados** (Acessados apenas pela própria classe), **protegidos** (Acessados pela própria classe e suas subclasses).

```jsx
class Post {
	public titulo: string;
	private autor: string;
	protected conteudo: string;
	createdAt: Date; //Caso não seja especificado o tipo de acesso, o padrão será o acesso publico.
	updatedAt: Date;

	//Construtor e métodos omitidos
}
```

#### 2.2. Construtor <a name="22-construtor">

Como o nome diz ele é usado na construção da classe, nele podemos passar os valores iniciais dos campos, podemos declarar métodos que devem ser executados toda vez que a classe for instanciada. Mesmo se não escrevermos um construtor, toda classe possui um construtor por padrão, no caso de não escrevermos nada esse construtor será vazio.

```jsx
class Foo {
  bar: string = "";

  constructor(bar: string) {
    this.bar = bar;
  }

  //Métodos omitidos
}

class Bar {
  foo: string = "";
}

const foo = new Foo("teste");
const bar = new Bar();

console.log(foo.bar); //teste
console.log(bar.foo); //
```

#### 2.3. Métodos <a name="23-métodos">

São as “ações” que a classe pode executar, esses atos executados pelos métodos são chamados de comportamentos. Assim como os campos, os métodos também possuem diferentes tipos de acesso. Podem ser **públicos** (Acessados por qualquer um), **privados** (Acessados apenas pela própria classe), alem dos tipos de acesso os métodos possuem “tipos” diferentes. Podem ser **abstratos** (São métodos sem implementação, onde só passamos nome do método e parâmetros e as subclasses são obrigadas a implementa-lo), **estáticos** (São métodos que não tem acesso aos campos da classe e pode ser executados sem a necessidade de instanciar a classe).

Ex. A classe **Gato** tem como um de seus métodos o ato de **pular.**

```jsx
class Gato {
	//Campos e construtor omitidos

	public pular(altura: number): void {
		//Coloque aqui o algoritmo relacionado a ação de pular
	}

	private dormir(): void {
		//Coloque aqui o algoritmo relacionado a ação de dormir
	}

	abstract miar(som: string): void

	static andar(): void {
		//Coloque aqui o algoritmo relacionado a ação de andar
	}
}
```

### 3. Hierarquia das classes <a name="3-hierarquia-das-classes">

Como dito no começo do artigo, a forma como as classes se relacionam é extremamente importante, na OO um relacionamento se estabelece do uso da palavra chave **extends**, com o relacionamento estabelecido podemos trabalhar com a hierarquia das classes

#### 3.1. Superclasse e Subclasses <a name="31-superclasse-e-subclasses">

Superclasse ou Classe mãe é a classe que será estendida por outras classes, ela possui a mesma estrutura de uma classe qualquer, porem suas subclasses herdaram seu construtor, campos e métodos.

Subclasses ou classes filhas são as classes que estendem uma superclasse, ao fazer essa extensão, a subclasse herdam o construtor, campos e métodos da superclasse, podendo acessa-los e utiliza-los de acordo com as necessidades.

```jsx
class Animal {}
class Gato extends Animal {}
class Cachorro extends Animal {}
```

#### 3.2. Subclasses e Sub-subclasses <a name="32-subclasses-e-sub-subclasses">

Além da estrutura citada a cima, onde existe 1 superclasse e N subclasses, existe outro tipo de hierarquia que é, as subclasses serem superclasses de outras classes abaixo na hierarquia, algo parecido com:

```jsx
class Animal {}

class Gato extends Animal {}
class Cachorro extends Animal {}

class Persa extends Gato {}

class Pitbull extends Cachorro {}
class Bulldog extends Cachorro {}
```

Ao passo que a estrutura vai crescendo verticalmente, as subclasses no nível mais baixo vão tendo acesso as superclasses acima, mesmo não estendo-as diretamente estendendo-as, no nosso exemplo o nível mais baixo são as classes “Persa”, “Bulldog” e “Pitbull”, essas classes podem acessar o construtor, campos e métodos da suas superclasses diretas Gato e Cachorro, mas também podem acessar a classe Animal.

### 4. Interfaces <a name="4-interfaces">

Naturalmente quando se fala de OO vem a cabeça o uso de classes, porem o uso exagerado de classe traz uma série de problemas que não existiriam sem elas, como por exemplo subclasses tendo acesso a métodos que não fazem sentido elas acessarem, métodos iguais que precisam ser escritos diversas vezes em diferentes classes para abranger o acesso de diferentes objetos, para evitar esses problemas e conseguir desenvolver um código funcional, utilizamos as interfaces. Uma interface pode ser interpretada como um contrato, neste contrato declaramos tudo que deve ter e ser feito por quem assina-lo, trazendo para o contexto técnico, na interface declaramos campos e/ou métodos, mas sem implementa-los, nos campos declaramos seu nome e tipo, nos métodos declaramos seu nome, parâmetros e tipo de retorno, a implementação fica a cargo das classes que utilizarem a interface, bem como quando utilizar os campos e métodos. Para utilizar uma interface usamos a palavra **implements**, uma classe pode implementar N interfaces.

```jsx
interface foo {
  bar(param1: string): string;
}

interface bar {
  foo: string;
}

interface baz {
  fuu(zoo: number): void;
}

class xpto1 implements foo {
  bar(param1: string): string {
    return param1.toLowerCase();
  }
}

class xpto2 implements bar {
  foo: string = "campo vindo da interface";
}

class xpto3 implements foo, bar, baz {
  foo: string = "campo obrigatório por causa da interface bar";

  bar(param1: string): string {
    return param1.toUpperCase();
  }

  fuu(zoo: number): void {
    zoo + 1;
  }
}
```