Aula 02 a 03 - Type hinting / Namespaces
Podemos definir os tipos dos dados de entrada diretamente na
definição de entrada de parametros. Isso evita termos que fazer
testes condicionais para validar o tipo dos atributos.
Já o namespace permite definir uma referencia para a classe permitindo que tenhamos classes de mesmo nome em contextos de namespace diferentes.

Já o namespace permite definir uma referencia para a classe permitindo que tenhamos classes de mesmo nome em contextos de namespace diferentes.
Aula 04 - Autoload
O autoload é um carregamento automático de classes. Sua
padronização pode ser encontrada na página
PHP-FIG: PSR-4.
Nessa página podemos buscar em exemplos um autoloader baseado
em classes.
Com isso criamos um arquivo Autoload.php. Nesse arquivo incluimos o código recuperado no exemplo do autoloader. Nesse arquivo devemos ajustar o nome do fornecedor do namespace e o nome da classe que usaremos para instanciar o autoloader.
Feito isso podemos remover a inclusão dos arquivos de classe no arquivo que irá instanciá-las. Ao invés disso imcluimos o arquivo do autoload.
require __DIR__ . '/src/Autoload.php';
Em seguida instanciamos a classe do autoloader, registramos essa classe e adicionamos o namespace:
Para finalizar passamos a rotina de inicialização do autoloader para um arquivo separado, de modo que possamos incluir quantos namespaces sejam necessários.

Com isso criamos um arquivo Autoload.php. Nesse arquivo incluimos o código recuperado no exemplo do autoloader. Nesse arquivo devemos ajustar o nome do fornecedor do namespace e o nome da classe que usaremos para instanciar o autoloader.
Feito isso podemos remover a inclusão dos arquivos de classe no arquivo que irá instanciá-las. Ao invés disso imcluimos o arquivo do autoload.
require __DIR__ . '/src/Autoload.php';
Em seguida instanciamos a classe do autoloader, registramos essa classe e adicionamos o namespace:
require __DIR__ . '/src/Autoload.php';
$autoload = new Jean\Autoload;
$autoload->register();
$autoload->addNamespace('Jean', 'src');
A partir desse momento podemos criar quantas classes quisermos no
diretório 'src' e desde que elas tenham o namespace do
fornecedor definido elas são carregadas sem a necessidade do
require. $autoload = new Jean\Autoload;
$autoload->register();
$autoload->addNamespace('Jean', 'src');
Para finalizar passamos a rotina de inicialização do autoloader para um arquivo separado, de modo que possamos incluir quantos namespaces sejam necessários.
Aula 05 a 08 - Herança e polimorfismo / Abstração / Encapsulamento
/ Associação
Entre os pilares da Orientação a Objetos, já vimos a
herança que é a capacidade de extender os atributos e métodos
de uma classe para outras.
Já o polimorfismo é a capacidade de mudança nos atributos e métodos de classes.
Na prática temos que uma classe que herde métodos de outra, reescrevam esses métodos de acordo com sua própria necessidade, sem alterar a assinatura do método.
O polimorfismo ocorre não só quando sobreescrevemos um método, mas também quando implementamos métodos baseados em uma interface cujas características são diferentes para cada implementação.
Quando declaramos um método e inserimos após seu nome o tipo precedido por ':' (:string) estamos fazendo outra forma de type hinting, pois estamos definindo que o retorno do método tem que ter o tipo definido.
Outro pilar da OO a abstração é a característica de se criar classes com conteudos que podem ser expandidos conforme a necessidade da aplicação.
O encapsulamento é a característica em que criamos um código em diversas partes (encapsuladas) de modo a facilitar a manutenção e aprimoramento da aplicação, o que é um dos focos da OO.
A associação pode ser por composição ou por agregação. Quando é por composição determinada classe não tem razão de existir se não existirem classes que a complementem. Já por agregação uma classe pode existir e não fazer nada sem uma classe associada.

Já o polimorfismo é a capacidade de mudança nos atributos e métodos de classes.
Na prática temos que uma classe que herde métodos de outra, reescrevam esses métodos de acordo com sua própria necessidade, sem alterar a assinatura do método.
O polimorfismo ocorre não só quando sobreescrevemos um método, mas também quando implementamos métodos baseados em uma interface cujas características são diferentes para cada implementação.
Quando declaramos um método e inserimos após seu nome o tipo precedido por ':' (:string) estamos fazendo outra forma de type hinting, pois estamos definindo que o retorno do método tem que ter o tipo definido.
Outro pilar da OO a abstração é a característica de se criar classes com conteudos que podem ser expandidos conforme a necessidade da aplicação.
O encapsulamento é a característica em que criamos um código em diversas partes (encapsuladas) de modo a facilitar a manutenção e aprimoramento da aplicação, o que é um dos focos da OO.
A associação pode ser por composição ou por agregação. Quando é por composição determinada classe não tem razão de existir se não existirem classes que a complementem. Já por agregação uma classe pode existir e não fazer nada sem uma classe associada.
Aula 09 - Manipulando erros
Devemos sempre que possível criar classes para tratamento de erro.
Criamos o seguinte método para tratar erros adicionando a classe Exception (ver documentação PHP Documentation):
A classe Exception é precedida por '\' para escapar o namespace definido (pois é uma classe que não faz parte do namespace).
Com esse método podemos por exemplo manipular uma requisição com try...catch e retornar a mensagem padronizada na nossa Exception:

Criamos o seguinte método para tratar erros adicionando a classe Exception (ver documentação PHP Documentation):
public function select(bool $data)
{
if ($data) {
return [];
}
throw new \Exception('Data deveria ser positivo', 1);
}
{
if ($data) {
return [];
}
throw new \Exception('Data deveria ser positivo', 1);
}
A classe Exception é precedida por '\' para escapar o namespace definido (pois é uma classe que não faz parte do namespace).
Com esse método podemos por exemplo manipular uma requisição com try...catch e retornar a mensagem padronizada na nossa Exception:
try {
$orm = new Jean\DB\ORM;
$orm->select(false);
} catch (\Exception $e) {
echo $e->getMessage();
}
Podemos ainda criar classes de tratamento de erro que herdam
(extends) a classe Exception. Com isso podemos
personalizar as mensagens enviadas para o tratamento.
$orm = new Jean\DB\ORM;
$orm->select(false);
} catch (\Exception $e) {
echo $e->getMessage();
}
Aula 10 a 11 - Métodos interceptadores
Alguns métodos interceptadores são:
__construct() que é o método construtor, que é sempre executado;
__call() retorna os dados enviados à classe quando nenhum método for encontrado
__toString() permite retornar os dados do objeto em formato de string.
__set() esse método insere os pares chave valor mesmo em atributos private. Pode ser utilizado para substituir a criação do método set. Porém para manter a proteção dos atributos podemos criar uma lógica para que só seja utilizado em casos em que não haja o método set criado:

__construct() que é o método construtor, que é sempre executado;
__call() retorna os dados enviados à classe quando nenhum método for encontrado
__toString() permite retornar os dados do objeto em formato de string.
__set() esse método insere os pares chave valor mesmo em atributos private. Pode ser utilizado para substituir a criação do método set. Porém para manter a proteção dos atributos podemos criar uma lógica para que só seja utilizado em casos em que não haja o método set criado:
public function __set($propertie, $value)
{
$method = 'set' . ucFirst($propertie);
if (method_exists($this, $method)) {
$this->$method($value);
} else {
$this->$propertie = $value;
}
}
Podemos fazer o mesmo com o __get(). {
$method = 'set' . ucFirst($propertie);
if (method_exists($this, $method)) {
$this->$method($value);
} else {
$this->$propertie = $value;
}
}
public function __get($propertie)
{
$method = 'get' . ucFirst($propertie);
if (method_exists($this, $method)) {
return $this->$method();
} else {
return $this->$propertie;
}
}
{
$method = 'get' . ucFirst($propertie);
if (method_exists($this, $method)) {
return $this->$method();
} else {
return $this->$propertie;
}
}
Aula 12 - Traits
Traits são classes que criam heranças horizontais, ou seja,
não geram dependencias como a interface ou as classes
pai
Elas são criadas com a palavra reservada trait (ao invés de class) e gera uma classe que não precisa ser extendida nem implementada. Basta que a declaremos dentro da classe que queremos utiliza-la com a palavra use.

Elas são criadas com a palavra reservada trait (ao invés de class) e gera uma classe que não precisa ser extendida nem implementada. Basta que a declaremos dentro da classe que queremos utiliza-la com a palavra use.