Uma abordagem prática de Orientação a Objetos com PHP
http://www.georgemendonca.com.br
• Introdução
– Versão atual: PHP 5.3 - http://www.php.net/releases.
• 5.3.0 (30/06/2009)
• 5.3.1 (19/11/2009)
• 5.3.2 (04/04/2010)
• 5.3.3 (22/07/2010)
• 5.3.4 (09/12/2010)
• 5.3.5 (06/01/2011)
• 5.3.6 (17/03/2011)
Orientação a Objetos
2
• Introdução
– Possui suporte a OO desde a versão 3.
– A versão 4 foi reescrita com o objetivo de tornar mais
rápida e estável.
– No PHP 5 foi desenvolvido um novo modelo de
objetos, completamente reescrito, mais completo,
permitindo uma performance melhor e mais
vantagens.
Orientação a Objetos
3
• Introdução
– Diferenças entre o PHP 4 e o PHP 5
• PHP 4 - Classes simples:
– Uma tentativa a orientação à objetos
– Porém sem muitos conceitos considerados importantes para
uma linguagem orientada a objetos
Orientação a Objetos
4
• Introdução
– Diferenças entre o PHP 4 e o PHP 5
Orientação a Objetos
5
<?php
Class Php4
{
/**
* Atributos simples
*/
var $a;
var $b;
var $c;
/**
* Método construtor da classe PHP 4
* Métodos simples
*/
function Php4()
{
}
}
Diagrama de Classe
• Introdução
– Diferenças entre o PHP 4 e o PHP 5
• PHP 5 - Classes mais completas e uso de padrões:
– Com implementação de recursos semelhantes às linguagens
de programação como C++ e Java.
Orientação a Objetos
6
• Introdução
– Diferenças entre o PHP 4 e o PHP 5
Orientação a Objetos
7
<?php
Class Php5
{
/**
* Visibilidade de atributos (encapsulamento)
*/
public $a;
protected $b;
private $c;
/**
* Método construtor da classe PHP 5
* Visibilidade de métodos
*/
public function __construct()
{
}
}
Diagrama de Classe
• Escrevendo uma classe
– A definição de uma classe em PHP começa com a
palavra-chave class, seguido do nome_da_classe,
que pode ser qualquer nome que não seja uma
palavra reservada no PHP.
– Seguido por um par de chaves “ { } “, que contém a
definição dos atributos (ou propriedades) e
métodos (ou comportamentos) da classe.
Orientação a Objetos
8
• Escrevendo uma classe
Orientação a Objetos
9
<?php
class Nome_da_Classe
{
encapsulamento $atributo1;
...
encapsulamento function nome_metodo( [argumento1, ...] )
{
/**
* Implementação do comportamento do método.
* Como uma função, um método pode retornar
* um valor se necessário.
*/
[return]
}
...
}
• A variável $this
– Uma pseudo variável $this está disponível quando
um método da classe é chamado dentro de um
contexto de objeto.
– Sua implementação normalmente se encontra dentro
do escopo de um método.
– $this é uma referência para o objeto ao chamar um
método ou um atributo.
Orientação a Objetos
10
• A variável $this
Orientação a Objetos
11
<?php
Class Nome_da_Classe
{
encapsulamento $atributo1;
...
encapsulamento function nome_metodo()
{
// A variável $this referencia o objeto
// chamado em tempo de execução no script.
return $this->atributo1;
}
...
}
• A variável $this
– Observação importante para o entendimento:
• Há uma certa dificuldade em entender a utilização desta variável
em uma classe em qualquer linguagem de programação. Então:
» Imagine uma classe como a planta de uma casa.
» Cada casa construída é um objeto desta planta, porém cada um com
sua implementação específica (local, alterações, material, etc.).
» Relacionando, a variável $this referencia cada objeto criado desta
classe (cada casa construída com base nesta planta). ;D
Orientação a Objetos
12
• Encapsulamento de atributos e métodos
– O encapsulamento (ou visibilidade) de um atributo ou de um método pode ser definido prefixando a declaração com as palavras-chave:
• public, protected e private.
– Public podem ser acessados por todo script.
– Protected limita o acesso a classes herdadas e para
classe que define o objeto.
– Private limita a visibilidade para apenas a classe que
define o objeto.
Orientação a Objetos
13
• Encapsulamento de atributos e métodos
Orientação a Objetos
14
<?php
Class Encapsulamento
{
// Visível em todo o script
public $atributoPublico;
// Visível nas classes e subclasses
protected $atributoProtegido;
// Visível apenas na classe
private $atributoPrivado;
public function metodoPublico()
{
// Visível em todos os scripts
}
protected function metodoProtegido()
{
// Visível em classes e subclasses
}
private function metodoPrivado()
{
// Visível apenas na classe
}
}
Diagrama de Classe
• Construtores e Destrutores
– PHP 5 permite que os desenvolvedores declarem
métodos construtores para as classes. Isto é feito
através do método mágico __construct().
– Classes que tem um método construtor chamam esse
método cada vez que um objeto novo é criado, sendo
apropriado para qualquer inicialização que o objeto
necessite no momento em que é instanciado.
Orientação a Objetos
15
• Construtores e Destrutores
Orientação a Objetos
16
<?php
Class ConstrutorDestrutor
{
private $a;
private $b;
public function __construct($a, $b)
{
$this->a = $a;
$this->b = $b;
}
public function __destruct()
{
$this->a = null;
$this->b = null;
}
}
Diagrama de Classe
O construtor da classe inicializa os valores dos atributos do objeto caso necessário.
Libera o espaço em memória reservado para o objeto no encerramento do script ou quando chamado explicitamente.
• Instanciando o objeto da classe
– Para criar uma instância de um objeto da classe, um
novo objeto deve ser criado (instanciado) e atribuído à
uma variável.
– Para tanto é necessário a chamada da palavra reservada
new seguido do nome da classe para criar um novo
objeto, instanciando então a classe (ou um objeto da
classe).
Orientação a Objetos
17
• Instanciando o objeto da classe – Editor utilizado: Eclipse (Eclipse for PHP Developers)
– Estrutura de pasta proposta para os exemplos:
– Boas práticas:
• Criar uma classe por arquivo e nomear arquivo com o nome da classe
– Ex.: MinhaClasse.php
• Tipificar as variáveis PHP na nomenclatura da variável
– Ex.: $aCidades [ ] = $oCidade (array de cidades recebe objeto cidade)
• Utilize caminho relativo na inclusão de arquivos
– "./pasta/arquivo.php"
• Se tiver somente código PHP não feche a tag PHP (porque?)
Orientação a Objetos
18
• Instanciando o objeto da classe
Orientação a Objetos
19
<?php
require_once './class/php4.php';
require_once './class/php5.php';
require_once './class/Encapsulamento.php';
require_once './class/ConstrutorDestrutor.php';
$oPhp4 = new Php4();
$oPhp5 = new Php5();
$oEncap = new Encapsulamento();
$oConstr = new ConstrutorDestrutor(1, 2);
echo "<pre>";
print_r($oPhp4);
print_r($oPhp5);
print_r($oEncap);
print_r($oConstr);
$oConstr->__destruct();
print_r($oConstr);
• Instanciando o objeto da classe
Orientação a Objetos
20
Saída: Php4 Object ( [a] => [b] => [c] => ) Php5 Object ( [a:Php5:private] => [b:Php5:private] => [c:Php5:private] => ) Encapsulamento Object ( [atributoPublico] => [atributoProtegido:protected] => [atributoPrivado:Encapsulamento:private] => )
• Exercitando
– Crie a classe ao lado, seus
atributos e métodos e a manipule
através de um arquivo com o
nome appFuncionario.php.
Orientação a Objetos
21
Diagrama de Classe
• Herança - Conceitos
– Como no mundo real, em orientação a objetos a palavra
herança sugere a construção de uma classe com base em
outra já existente.
– Ou seja, a criação de uma nova classe que herda as
características, propriedades e comportamentos de uma
classe base (ou classe pai) .
Orientação a Objetos
22
• Herança - Conceitos
– Tal conceito é conhecido também como Generalização.
– Herança permite que a classe filha usufrua das propriedades e
comportamentos da classe pai (exceto privados), assim como a
alteração de tais comportamentos e a criação de novas
propriedades e atributos específicos.
Orientação a Objetos
23
• Herança no PHP
– Em PHP uma classe pode herdar propriedades e métodos de
outra classe usando a palavra-chave extends na sua
declaração.
– Não é possível herdar classes múltiplas, uma classe só pode
herdar uma classe base (ou classe pai, ou ainda classe
genérica).
– Para acessar atributos e métodos da classe pai, utiliza-se a
palavra reservada parent seguida de dois pontos duplos (::).
Orientação a Objetos
24
Nota: Construtores pais não são chamados implicitamente se a classe filha define um construtor. Para executar o construtor da classe pai, uma chamada a parent::__construct() dentro do construtor da classe filha é necessária.
• Herança no PHP
– Vejamos o diagrama ao lado.
– A classe Dependentes (classe filha)
estende a classe Funcionario (último
exercício), aplicando o conceito de
generalização (herança).
– A classe Dependentes herda as
propriedades e atributos da classe
Funcionario (classe pai).
Orientação a Objetos
25
Diagrama de Classe
• Herança no PHP – Implementando o diagrama de classe:
Orientação a Objetos
26
<?php
class Dependentes extends Funcionario
{
private $dependentes = array();
public function __construct($dependentes)
{
// Implementações de inicialização do objeto
}
public function imprimeDadosFuncionario()
{
// Impressão dos dados do Funcionário
}
}
• Herança no PHP – Exemplo: Implementação prática.
Orientação a Objetos
27
<?php
class Dependentes extends Funcionario {
private $dependentes = array();
public function __construct( $dependentes ) {
$this->dependentes = $dependentes;
}
public function imprimeDadosFuncionario() {
echo "<b>Matrícula</b>: {$this->getMatricula()} <br />
<b>Nome</b>: {$this->getNome()} <br />
<b>RG</b>: {$this->getRg()} <br />
<b>Departamento</b>: {$this->getDepartamento()}
<br />
<b>Dependentes</b>: <br />";
foreach ($this->dependentes as $value) {
echo " - {$value}<br />";
}
}
}
• Herança no PHP – Exemplo: Implementação prática (continuação).
Orientação a Objetos
28
<?php
// appFuncDependentes.php
require_once './class/Funcionario.php';
require_once './class/Dependentes.php';
//Exercício sobre Herança (Generalização)
$aDpendentes = array('Maria', 'Pedro', 'Lucas');
# Instanciando o objeto e passando o array de dependentes
$oDependentes = new Dependentes( $aDpendentes );
# Setando os dados do funcionário
$oDependentes->setMatricula('777');
$oDependentes->setNome('George');
$oDependentes->setRg('1234567');
$oDependentes->setDepartamento('Informática');
# Imprimindo dados dos dependentes
echo '<strong>Dados dos dependentes</strong>: <br />';
$oDependentes->imprimeDadosFuncionario();
Saída: Ficha do funcionário: Matrícula: 777 Nome: George RG: 1234567 Departamento: Informática Dependentes: - Maria - Pedro - Lucas
• Conversão da classe para string
– Impressão da classe:
– Erro:
– Correção deste problema convertento para string:
– Resultado:
Orientação a Objetos
29
Saída:
Catchable fatal error: Object of class Funcionario could not be converted to string in \var\www\...
<?php // appToString.php
require_once './class/Funcionario.php';
$oFuncionario = new Funcionario();
echo $oFuncionario;
// Adicionar à classe Funcionario (Funcionario.php)
public function __toString(){
return 'Classe Funcionario';
}
Saída:
Classe Funcionario
• Referência do objeto
– Sempre que uma variável do tipo objeto é atribuída a
uma outra variável, ele recebe somente a referência
deste objeto.
– Tais variáveis referenciam exatamente o mesmo
objeto.
Orientação a Objetos
30
<?php
require_once './class/Funcionario.php';
$oFuncionario = new Funcionario();
$oNovoFuncionario = $oFuncionario;
$oFuncionario->setDepartamento('RH');
echo "A matrícula do funcionário é: {$oNovoFuncionario->getDepartamento()}";
Saída:
A matrícula do funcionário é: RH
Departamento inserido no primeiro objeto O segundo objeto
também contém o Departamento inserido
• Clonagem de Objetos
– Necessário quando precisamos clonar um objeto,
criando outro espaço em memória ao invés de uma
referência.
– Neste caso é criada uma nova instância do objeto,
contendo as mesmas propriedades e métodos.
Orientação a Objetos
31
<?php // appClonagemObjeto.php
require_once './class/Funcionario.php';
$oFuncionario = new Funcionario();
$oNovoFuncionario = clone $oFuncionario;
$oFuncionario->setDepartamento('RH');
$oNovoFuncionario->setDepartamento('Informática');
echo "Departamento: {$oFuncionario->getDepartamento()} <br />";
echo "Departamento: {$oNovoFuncionario->getDepartamento()}";
Saída:
Departamento: RH Departamento: Informática
Um novo objeto é criado através da clonagem do primeiro.
• Atributos e Métodos Estáticos
– Declarar atributos ou métodos de uma classe como estáticos faz deles acessíveis sem precisar de instanciar a classe.
– A palavra reservada static é utilizada na declaração
de atributos e métodos estáticos.
Orientação a Objetos
32
• Atributos e Métodos Estáticos
– A referência aos atributos estáticos da classe é feita
através da palavra reservada self seguida de dois pontos
duplos (::) em vez de “$this->”.
– Um atributo declarado como estático não pode ser
acessado com um objeto instanciado da classe
(embora métodos estáticos podem).
Orientação a Objetos
33
• Atributos e Métodos Estáticos
Orientação a Objetos
34
<?php // Classe Matematica
class Matematica
{
public static function soma( $a, $b )
{
return $a + $b;
}
}
<?php // appMatematica.php
$num1 = 4;
$num2 = 5;
echo Matematica::soma($num1, $num2);
Saída:
9
Diagrama de Classe
• Overloading (Sobrecarga)
– Provê meios dinâmicos para manipular atributos
(propriedades) e métodos em PHP.
– Utilizados na manipulação de métodos e
propriedades não declarados explicitamente ou não
visíveis no escopo atual.
– Todos os métodos sobrecarregados devem ser
definidos como públicos.
– Este procedimento é feito através dos métodos
mágicos.
Orientação a Objetos
35
• Overloading (Sobrecarga)
– Sobrecarga de atributos:
• __set () : executado para a atribuição de valores em propriedades inacessíveis.
• __get () : utilizada para retornar valores de propriedades inacessíveis.
• __isset () : acionado para chamar isset () ou empty () em propriedades inacessíveis (PHP 5.1.0).
• __unset () : invocado para chamar unset () em propriedades inacessíveis (PHP 5.1.0).
Orientação a Objetos
36
• Overloading (Sobrecarga)
– Sobrecarga de métodos:
• __call () : acionado ao invocar métodos inacessíveis em um contexto de objeto.
• __callStatic() : acionado ao invocar métodos estáticos inacessíveis em um contexto de objeto (PHP 5.3.0).
Orientação a Objetos
37
• Overloading (Sobrecarga)
Orientação a Objetos
38
<?php // FuncionarioOverloading.php
class FuncionarioOverloading
{
private $matricula = null;
private $nome = null;
private $rg = null;
protected $departamento = null;
public function __construct( ) { }
public function __get( $atributo )
{
return $this->$atributo;
}
public function __set( $atributo, $valor)
{
$this->$atributo = $valor;
}
}
– Sobrecarregando
os atributos da
classe Funcionario
dos exemplos
anteriores:
• Overloading (Sobrecarga) – Sobrecarregando os atributos da classe Funcionario
dos exemplos anteriores:
Orientação a Objetos
39
<?php // appSobrecarga.php
require_once './class/FuncionarioOverloading.php';
$oFuncionario = new FuncionarioOverloading();
echo "<pre>";
print_r($oFuncionario);
$oFuncionario->__set('matricula','777');
$oFuncionario->__set('nome','George Mendonça');
$oFuncionario->__set('rg','1234567');
$oFuncionario->__set('departamento','Informática');
echo "<pre>";
print_r($oFuncionario);
echo "<br/><strong>Dados do funcionário</strong><br />
- Matrícula: {$oFuncionario->__get('matricula')}
- Nome: {$oFuncionario->__get('nome')}
- RG: {$oFuncionario->__get('rg')}
- Departamento: {$oFuncionario->__get('departamento')}";
• Overloading (Sobrecarga) – Sobrecarregando os atributos da classe Funcionario
dos exemplos anteriores:
Orientação a Objetos
40
Saída: FuncionarioOverloading Object ( [matricula:FuncionarioOverloading:private] => [nome:FuncionarioOverloading:private] => [rg:FuncionarioOverloading:private] => [departamento:protected] => ) FuncionarioOverloading Object ( [matricula:FuncionarioOverloading:private] => 777 [nome:FuncionarioOverloading:private] => George Mendonça [rg:FuncionarioOverloading:private] => 1234567 [departamento:protected] => Informática ) Dados do funcionário - Matrícula: 777 - Nome: George Mendonça - RG: 1234567 - Departamento: Informática
• Iteração de Objetos
– PHP 5 fornece uma maneira de definir objetos para que seja possível iterar atributos públicos de uma classe, como uma lista de itens.
– Por padrão, todas as propriedades visíveis (públicas) serão usadas para a iteração.
– Essa iteração é efetualda facilmente com a estrutura de controle foreach.
Orientação a Objetos
41
• Iteração de Objetos
Orientação a Objetos
42
<?php
Class Iteracao
{
public $nome = "George";
public $casado = true;
public $idade = 28;
}
Saída:
nome : George casado : 1 idade : 28
<?php // appIteracaoObjetos.php
require_once './class/IteracaoObjetos.php';
$oIteracao = new IteracaoObjetos();
foreach ($oIteracao as $atributo => $valor) {
print "$atributo : $valor <br />";
}
Atributo da classe Objeto da classe Valor do atributo
Diagrama de Classe
• Indução de Tipo
– PHP 5 implementa indução de tipo.
– Neste conceito, funções e métodos podem forçar
parâmetros a serem objetos de uma classe.
– Basta especificar o nome da classe no
desenvolvimento da função ou método.
– É possível também aplicar em arrays (PHP 5.1).
Orientação a Objetos
43
• Indução de Tipo
Orientação a Objetos
44
Class Aves // Classe Aves.php
{
public $galinha = "có có có!";
public $pato = "quá quá quá!";
}
Saída:
Galinha: có có có! Pato: quá quá quá! Assados: Hummmm!
Class AssarAves // Classe AssarAves.php
{
public $assados = "Hummmm!";
function cardapio( Aves $cardapio)
{
echo "Galinha: $cardapio->galinha<br />
Pato: $cardapio->pato<br />
Assados: $this->assados";
}
}
$oAves = new Aves();
$oAssarAves = new AssarAves();
$oAssarAves->cardapio($oAves);
• Reflection API
– Permite realizar a engenharia reversa de diversos
elementos em PHP5.
– É uma poderosa funcionalidade que nos permite
obter informações e metadados de classes,
objetos, funções, etc.
Orientação a Objetos
45
• Reflection API
Orientação a Objetos
46
<?php // appReflexao.php
require_once './class/IteracaoObjetos.php';
require_once './class/FuncionarioOverloading.php';
$oRefClasslIter = new ReflectionClass('IteracaoObjetos');
$oRefClasslFunc = new ReflectionClass('FuncionarioOverloading');
echo '<strong>Propriedades da classe IteracaoObjetos:</strong> <br />';
foreach ($oRefClasslIter->getProperties() as $value) {
echo $value.'<br />';
}
echo '<br /><strong>Dados da classe Funcionario:</strong> <br />';
echo "Nome da classe: {$oRefClasslFunc->getName()} <br />";
echo "Arquivo: {$oRefClasslFunc->getFileName()} <br />";
• Reflection API
Orientação a Objetos
47
Saída: Propriedades da classe IteracaoObjetos: Property [ public $nome ] Property [ public $casado ] Property [ public $idade ] Dados da classe Funcionario: Nome da classe: Funcionario Arquivo: /var/www/php5.3-objetos/10-reflexao/class/FuncionarioOverloading.php
• Autoload – Carregando classes
automaticamente
– Normalmente ao desenvolver aplicações orientadas a
objeto em PHP os desenvolvedores criam um arquivo
para cada definição de classe.
– Consequentemente uma lista de includes é
necessária para a inclusão de cada classe em
uso. No o PHP5 isso não é mais necessário.
Orientação a Objetos
48
• Autoload – Carregando classes automaticamente
– Com a função __autoload quando você tentar usar uma
classe/interface que ainda não foi definida, o script
engine tem uma última chance para carregar a classe
antes que o PHP aponte o erro.
– Esta função é chamada automaticamente.
Orientação a Objetos
49
• Autoload – Carregando classes
automaticamente
– Implementação a função autoload:
– Testando as classes Funcionario e Matematica:
Orientação a Objetos
50
<?php
function __autoload( $classe )
{
require_once "./class/{$classe}.php";
}
<?php // appAutoloadClasses.php
require_once './func/autoload.php';
$oFuncionario = new Funcionario;
echo $oFuncionario.'<br />';
echo Matematica::multiplicacao(4, 4).'<br />';
echo "<pre>";
print_r($oFuncionario);
• Autoload – Carregando classes
automaticamente
Orientação a Objetos
51
Saída:
Classe Funcionario 16 Funcionario Object ( [matricula:Funcionario:private] => [nome:Funcionario:private] => [rg:Funcionario:private] => [departamento:protected] => )
• Late Static Bindings (PHP 5.3)
– Permite referenciar uma classe chamada no contexto
de herança estática.
– Para tanto a palavra reservada static:: é utilizada na
chamada de um método estático, mas não somente
para métodos.
Orientação a Objetos
52
• Late Static Bindings (PHP 5.3)
– Limitação do self::
• Em um contexto de herança, por exemplo, referências
estáticas são resolvidas usando a classe na qual foi definida,
ou seja, a qual pertence. Mas não na classe a qual foi
chamada em tempo de execução.
– Late Static Bingings
• Resolve tal limitação através da palavra reservada static::
em vez de self::, referenciando a classe chamada em tempo
de execução em vez da classe que a define.
Orientação a Objetos
53
• Late Static Bindings (PHP 5.3)
– Exemplo
• Vamos implememtar o exemplo seguinte criando as classes
em um mesmo arquivo para facilitar:
– LateStaticBindings.php (classe)
• E para testar vamos implementar o arquivo:
– appLateStaticBindings.php
• Vejamos a implementação a seguir:
Orientação a Objetos
54
• Late Static Bindings (PHP 5.3)
Orientação a Objetos
55
• Late Static Bindings (PHP 5.3)
Orientação a Objetos
56
<?php
class X // X.php
{
public static function imprimeClasse()
{
echo 'Eu sou a classe '.__CLASS__;
}
public static function chamaClasse()
{
self::imprimeClasse();
}
}
class TesteX extends X // TesteX.php
{
public static function imprimeClasse()
{
echo 'Eu sou a classe '.__CLASS__;
}
}
Saída:
Eu sou a classe X
<?php // appLateStaticBindings.php
require_once './func/autoload.php';
TesteX::chamaClasse();
• Late Static Bindings (PHP 5.3)
Orientação a Objetos
57
• Late Static Bindings (PHP 5.3)
Orientação a Objetos
58
<?php
class Y // Y.php
{
public static function imprimeClasse()
{
echo 'Eu sou a classe '.__CLASS__;
}
public static function chamaClasse()
{
static::imprimeClasse();
}
}
class TesteY extends Y // TesteY.php
{
public static function imprimeClasse()
{
echo 'Eu sou a classe '.__CLASS__;
}
}
Saída:
Eu sou a classe X Eu sou a classe TesteY
<?php // appLateStaticBindings.php
require_once './func/autoload.php';
TesteX::chamaClasse();
echo '<br />';
TesteY::chamaClasse();
• Constantes do Objeto
– É possível definir valores constantes em cada
classe, permanecendo os mesmos e imutáveis.
– Constantes diferem de variáveis no não uso do
símbolo $ para declará-las ou utilizá-las. Mas
utilizando a palavra reservada const na declaração.
– Assim como os atributos estáticos são referenciadas
ou chamadas através da palavra reservada self do
PHP.
Orientação a Objetos
59
• Constantes do Objeto
– Como os atributos estáticos (static), valores
constantes não podem ser acessados a partir de
uma instância de um objeto (como por exemplo
$object::constante).
– O valor deve ser uma expressão constante, não
podendo ser (por exemplo) uma variável, um
atributo de uma classe, o resultado de uma
operação matemática ou uma chamada de função.
Orientação a Objetos
60
• Constantes do Objeto
– Classe de constantes:
Orientação a Objetos
61
// Classe CadastroEmpresas.php
class CadastroEmpresas
{
const TITULO_TELA = "Cadastro de Empresas";
const NOME = "Nome:";
const CNPJ = "CNPJ:";
const RAZAO_SOCIAL = "Razão Social:";
const BOTAO_SUBMIT = " >> Salvar ";
}
• Constantes do Objeto
– Implementação básica:
Orientação a Objetos
62
<?php // appConstantesdaClasse.php
require_once './func/autoload.php';
echo "
<p><strong>".CadastroEmpresas::titulo_tela."</strong></p>
<form>
".CadastroEmpresas::nome." <input type='text' value='' /><br />
".CadastroEmpresas::cnpj." <input type='text' value='' /><br />
".CadastroEmpresas::razao_social." <input type='text' value='' /><br /><br />
<input type='submit' value='".CadastroEmpresas::botao_submit."' />
</form>";
Saída:
• Classes e Métodos Abstratos
– PHP 5 introduz métodos e classes abstratos.
– Não é permitido criar uma instância de uma classe que foi
definida como abstrata.
– Qualquer classe que contêm pelo menos um método
abstrato deve também ser abstrata.
– Métodos definidos como abstratos simplesmente
declaram a assinatura do método, eles não podem
definir a implementação.
Orientação a Objetos
63
• Classes e Métodos Abstratos
– Quando uma classe herda uma classe abstrata, todos
os métodos marcados como abstratos na declaração da
classe pai devem ser definidos na classe filha.
– Além disso, esses métodos devem ser definidos com a
mesma visibilidade ou mais fraca.
– Por exemplo, se um método abstrado é definido como
protected, a implementação do método deve ser definida
como protected ou public.
Orientação a Objetos
64
• Classes e Métodos Abstratos
– Exemplo 01 - Classe Abstrata Venda
Orientação a Objetos
65
<?php // Classe Abstrata Venda.php
abstract class Venda
{
private $valor = 0.0;
private $desconto = 0.0;
public function __set($atributo, $valor)
{
$this->$atributo = $valor;
}
public function __get($atributo)
{
return $this->$atributo;
}
}
• Classes e Métodos Abstratos
– Exemplo 01 - Classe Orcamento
Orientação a Objetos
66
<?php // Classe Orcamento.php
class Orcamento extends Venda
{
private $taxa = array('cheque' => 1.10, 'cartao' => 1.18 );
public function vendaVista()
{
return $this->__get('valor') - $this->desconto;
}
public function vendaCheque()
{
return ($this->__get('valor')*$this->taxa['cheque']) - $this->desconto;
}
public function vendaCartao()
{
return $this->__get('valor')*$this->taxa['cartao'] - $this->desconto;
}
}
• Classes e Métodos Abstratos
– Exemplo 01 – Calculando o orçamento
Orientação a Objetos
67
<?php // appOrcamento.php
require_once './func/autoload.php';
$oOrcamento = new Orcamento();
$oOrcamento->__set('valor', 90);
$oOrcamento->__set('desconto', 10);
echo "<strong> === Orcamento === </strong><br /><br />";
echo "Preço: {$oOrcamento->__get('valor')}<br />";
echo "Desconto: {$oOrcamento->__get('desconto')}<br />";
echo "À vista: {$oOrcamento->vendaVista()}<br />";
echo "Cheque: {$oOrcamento->vendaCheque()}<br />";
echo "Cartão: {$oOrcamento->vendaCartao()}<br />";
Saída:
=== Orçamento === Preço: 90 Desconto: 10 À vista: 80 Cheque: 89 Cartão: 96.2
• Classes e Métodos Abstratos
– Exemplo 02 – Método abstrato imprimeOrcamento
Orientação a Objetos
68
// Classe Abstrata Venda.php
abstract class Venda
{
private $valor = 0.0;
private $desconto = 0.0;
public function __set($atributo, $valor)
{
$this->$atributo = $valor;
}
public function __get($atributo)
{
return $this->$atributo;
}
abstract function imprimeOrcamento($valor, $desconto);
}
• Classes e Métodos Abstratos
– Exemplo 02 – Adição do método abstrato
imprimeOrcamento
Orientação a Objetos
69
// Classe Orcamento.php
class Orcamento extends Venda
{
...
public function imprimeOrcamento($valor, $desconto)
{
$this->__set('valor', $valor);
$this->__set('desconto', $desconto);
echo "<strong> === Orcamento === </strong><br /><br />";
echo "Preço: {$this->__get('valor')}<br />";
echo "Desconto: {$this->__get('desconto')}<br />";
echo "À vista: {$this->vendaVista()}<br />";
echo "Cheque: {$this->vendaCheque()}<br />";
echo "Cartão: {$this->vendaCartao()}<br /><br />";
}
...
}
• Classes e Métodos Abstratos
– Exemplo 02 – Adição do método abstrato
imprimeOrcamento
Orientação a Objetos
70
<?php // appVendaMetodoAbstrato.php
require_once './func/autoload.php';
$oOrcamento = new Orcamento();
$oOrcamento->imprimeOrcamento(90, 10);
Saída:
=== Orçamento === Preço: 90 Desconto: 10 À vista: 80 Cheque: 89 Cartão: 96.2
• Interfaces
– Interfaces de Objetos permitem a criação de código que
especifica quais métodos e variáveis uma classe deve
implementar, sem ter que definir como esses métodos
serão tratados.
– A Interface é um contrato da classe. Interfaces são
definidas usando a palavra-chave 'interface', da mesma
maneira que uma classe comum, mas sem nenhum dos
métodos ter seu conteúdo definido.
Orientação a Objetos
71
• Interfaces
– Todos os métodos declarados em uma interface devem ser
public, essa é a natureza de uma interface. Para implementar
uma interface, o operador implements é usado.
– Todos os métodos na interface devem ser implementados na
classe; não fazer isso resultará em um erro fatal.
– Classes podem implementar mais de uma interface se assim
for desejado, separando cada interface com uma vírgula.
Orientação a Objetos
72
Nota: Uma classe não pode implementar duas interfaces que compartilham o mesmo nome uma vez que isso causaria ambiguidade.
• Interfaces
– Exemplo 01 - Interface OperacoesMatematicas
Orientação a Objetos
73
<?php //IOperacoesMatematicas.php
interface IOperacoesMatematicas
{
public static function soma($x, $y);
public static function subtracao($x, $y);
public static function multiplicacao($x, $y);
public static function divisao($x, $y);
public static function imprimeOperacoes($x, $y);
}
• Interfaces
– Exemplo 01 – Classe OpMatematicas que implementa a
interface OperacoesMatematicas
Orientação a Objetos
74
<?php // OpMatematicas.php
class OpMatematicas implements IOperacoesMatematicas
{
public static function soma($x, $y){ return $x + $y; }
public static function subtracao($x, $y) { return $x - $y; }
public static function multiplicacao($x, $y) { return $x * $y; }
public static function divisao($x, $y) {
return ($y <> 0) ? $x / $y : 'Divsão por zero!';
}
public static function imprimeOperacoes($a, $b) {
echo "<b>As operacoes matematicas entre $a e $b sao</b>: <br />";
echo "Soma: ".OpMatematicas::soma($a, $b)."<br />";
echo "Subtracao: ".OpMatematicas::subtracao($a, $b)."<br />";
echo "Multiplicacao: ".OpMatematicas::multiplicacao($a, $b)."<br />";
echo "Divisao: ".OpMatematicas::divisao($a, $b)."<br />";
}
}
• Interfaces
– Exemplo 01 – Aplicação appOpMatematicas
Orientação a Objetos
75
<?php // appOpMatematicas.php
require_once './func/autoload.php';
if(isset($_POST['a']) and isset($_POST['b']))
{
$a = $_POST['a'];
$b = $_POST['b'];
OpMatematicas::imprimeOperacoes($a, $b);
}
else
{
?>
<form method="post" id="operacoes">
1º Número: <input type="text" name="a" /> <br />
2º Número: <input type="text" name="b" /> <br />
<input type="submit" value=" >> Calcular " />
</form>
<?php
}
Saída:
As operacoes matemáticas entre 7 e 9 são: Soma: 16 Subtracao: -2 Multiplicacao: 63 Divisao: 0.77777777777778
• Polimorfismo
– É a capacidade de dois ou mais objetos de diferentes classes responderem à mesma mensagem de diferentes maneiras. Ou seja, é um recurso que possibilita que objetos diferentes sejam tratados por uma interface única.
– O Polimorfismo se define então na implementação de
diversos comportamentos em diferentes classes, que
se relacionam através de uma única Interface ou
Superclasse.
Orientação a Objetos
76
• Polimorfismo
Orientação a Objetos
77
interface IAnuncioImobiliaria // IAnuncioImobiliaria.php
{
public static function imprimeDados();
}
class Anuncio1 implements IAnuncioImobiliaria // Anuncio1.php
{
private static $dados = 'Casa, 2 quartos, sala, cozinha,
R. 37, Qd. 32, JD Oriente, Cuiabá-MT;';
public static function imprimeDados() {echo self::$dados; }
}
class Anuncio2 implements IAnuncioImobiliaria // Anuncio2.php
{
public static $dados = 'AP, 3 quartos, sala, cozinha, 2 garagens,
R. Barão Franca, Qd. 02, Rodovalho, Goiânia-GO;';
public static function imprimeDados() {echo self::$dados; }
}
class Anuncio3 implements IAnuncioImobiliaria // Anuncio3.php
{
public static $dados = 'Sobrado, 5 quartos, 2 salas,
2 cozinhas, 3 garagens, SEPN, Qd. 205, Brasília-DF';
public static function imprimeDados() {echo self::$dados; }
}
• Polimorfismo
Orientação a Objetos
78
<?php // appAnuncios.php
require_once './func/autoload.php';
echo '<b>Anúncio imobiliário</b>: <br /><br />';
Anuncio1::imprimeDados();
echo '<br />';
Anuncio2::imprimeDados();
echo '<br />';
Anuncio3::imprimeDados();
Saída: Anúncio imobiliário: Casa, 2 quartos, sala, cozinha, R. 37, Qd. 32, JD Oriente, Cuiabá-MT; AP, 3 quartos, sala, cozinha, 2 garagens, R. Barão Franca, Qd. 02, Rodovalho, Goiânia-GO; Sobrado, 5 quartos, 2 salas, 2 cozinhas, 3 garagens, SEPN, Qd. 205, Brasília-DF.
• Exceções
– PHP 5 tem um modelo de exceção é similar ao de
outras linguagens de programação. Uma exceção pode
ser disparada (thrown), ou pega (caught ou "catched")
no PHP.
– Podemos implementar um código PHP em um bloco try,
para facilitar a captura de exceções em potencial.
– Cada bloco try, deve ter pelo menos um bloco catch
correspondente.
Orientação a Objetos
79
• Exceções
– Vários blocos catch podem ser usados para pegar
diferentes classes de exceções.
– A execução normal (quando nenhuma exceção é
disparada dentro de um bloco try ou quando um
catch compatível com a classe da exceção disparada
não estiver presente) continuará após o último bloco
catch definido na sequência.
– Exceções podem ser disparadas (ou re-disparadas)
dentro de um bloco catch.
Orientação a Objetos
80
• Exceções
– Quando uma exceção é disparada, o código logo
após à instrução não será executada, e o PHP
tentará achar o primeiro bloco catch correspondente
à exceção disparada.
Orientação a Objetos
81
• Exceções
– Criando uma classe de Exceção para uma classe
Orientação a Objetos
82
// DivisaoException.php
class DivisaoException extends Exception {}
// Divisao.php
class Divisao
{
public function __construct($a, $b)
{
if ($b == 0)
{
throw new DivisaoException('Erro - Divisão por zero!');
}
}
}
• Exceções
– Criando uma aplicação para disparar a Exceção
Orientação a Objetos
83
Saída:
Mensagem: Erro - Divisão por zero! Linha: 8 Arquivo: /var/www/php5.3-objetos/17-excecoes/class/Divisao.php Codigo: 0
<?php
require_once './func/autoload.php';
try {
$oDivisao = new Divisao(5, 0);
} catch (DivisaoException $e) {
echo "Mensagem: {$e->getMessage()} <br />
Linha: {$e->getLine()} <br />
Arquivo: {$e->getFile()} <br />
Codigo: {$e->getCode()}";
}
Até o próximo FLISOL!
85