Não está nada fácil a migração do site. Mas, na próxima semana estará no ar nosso novo layout.
Estou preparando também uma seqüência de aulas sobre JSP.
Aguardem!
sábado, 31 de março de 2012
quinta-feira, 29 de março de 2012
Curso de PHP Orientado a Objetos - Parte 9
![]() |
| Imagem meramente ilustrativa |
Para conhecer as demais partes, clique aqui.
Ao final deste artigo, você será capaz de:
- Entender o que são os métodos interceptores;
- Fazer uso dos métodos __set(), __get() e __call().
Intercepções
Métodos de intercepção são métodos especiais predefinidos no PHP. Seus nomes são reservados, todos prefixados com dois caracteres "_" (underscore) no início.
Os métodos __set(), __get() e __call são alguns desses métodos. Trata-se de métodos opcionais e geralmente utilizados para executarem ações consideradas "especiais" e específicas.
__set()
O método __set() é invocado toda vez que um atributo não declarado da classe recebe a atribuição de um valor. Este método espera dois parâmetros, o primeiro contendo o nome do atributo e o segundo seu valor.
Em resumo, toda vez que for atribuído um valor a uma propriedade do objeto, automaticamente esta atribuição passa pelo método __set().
Para facilitar o entendimento, vamos ao exemplo:
/* Vamos crair a classe Pessoa
* com somente uma propriedade
* chamada Idade.
*/
class Pessoa{
private $Idade;
/* Quando tentarmos
* atribuir um valor
* para a propriedade idade
* o método __set() entre em ação
*/
public function __set( $propriedade, $valor ){
if( $propriedade == "Idade" ){
if( is_integer($valor) && strlen($valor) > 1 ){
$this->Idade = $valor;
echo "Valor: " . $valor . " Atribuído à propriedade: " . $propriedade;
}else{
echo "Valor: " . $valor . "NÃO atribuído à propriedade: " . $propriedade;
}
}
}
}
$leandro = new Pessoa();
$leandro->Idade = 27;
Observe que criamos o objeto normalmente (linha 36) e quando fomos atribuir 27 a propriedade idade do objeto, nosso amigo __set() interceptou, validou e só assim, permitiu ou não que o valor chegasse de fato ao atributo $idade.
Lembre-se, o __set() sempre espera dois parâmetros: $propriedade e $valor. Esses sempre devem ser verificados.
Imagine que em sua aplicação você possui a propriedade senha. Você pode utilizar o __set() para validar se a senha informada pelo usuário atende todos os requisitos necessário e só depois, a propriedade recebe o conteúdo (caso hipotético).
__get()
Análogo ao método __set(), o __get() é chamado quando um atributo da classe precisa ser retornado para o objeto. Ele espera um parâmetro, que será preenchido com o nome do atributo chamado.
Para exemplificar melhor o uso do __get(), vamos ao exemplo:
class Carro{
public $Nome;
private $Valor;
const MargemLucro = 8;
public function __construct($Nome, $Valor){
$this->Nome = $Nome;
$this->Valor = $Valor;
}
/* Quando o usuario requisitar
* uma propriedade, o __get()
* irá interceptar, verificar se a
* propriedade é a "Valor" e realizar
* o ajuste da margem de lucro
*/
function __get($Propriedade){
if( $Propriedade == "Valor" ){
$valor_reajustado = $this->Valor * ( 1 + self::MargemLucro / 100 );
return "R$ " . number_format($valor_reajustado, 3, ',', '.');
}
}
}
$vectra = new Carro("Vectra 2.0", 40.000);
echo $vectra->Valor;
Perceba que ao executar, quando realizamos a requisição a propriedade Valor, o método __get() faz a intercepção, ajusta o valor para a margem de lucro pré-definida além de formatar e só assim o valor e entregue.
Esta é um uso clássico do método __get().
__call()
Diferente dos métodos __set() e __get, o método __call() entra em ação quando é feita uma chamada a um método (não mais uma propriedade) que não existe. Sempre que um método não existir no objeto, automaticamente a execução será direcionada para ele que também recebe dois parâmetros, o nome e o parâmetro informados, assim ele pode decidir o que fazer nesta situação.
Vamos ao exemplo para entender melhor:
class Carro{
public $Nome;
private $Valor;
const MargemLucro = 8;
public function __construct($Nome, $Valor){
$this->Nome = $Nome;
$this->Valor = $Valor;
}
//Este é o método que fará a intercepção
function __call($Metodo, $Parametros){
echo "Método executado: " . $Metodo;
echo "Parâmetros do método:< br />";
// Um array para mostrar os parametros passados
foreach ( $Parametros as $Chave => $Parametro ){
echo "Parâmetro {$Chave} = " . $Parametro;
}
}
}
$vectra = new Carro("Vectra s.0", 40.000);
// Opa!! Que método é esse?? Ah, deixa que o __call cuida
echo $vectra->DefineCaracteristicas("Preto",2.0,"4 portas");
Ao executar, será mostrado todas as características passadas pelo método DefineCaracteristicas, justamente pela intercepção realizada pelo método __call(). Mesmo não tendo este método na classe.
Existem diversos outros métodos considerados especiais, clique aqui para consultar a lista completa.
Lembre-se que estes métodos foram projetados para facilitar a vida do programador, grandes frameworks como Zend fazem uso dessa funcionalidade para atribuir de forma dinâmica nas camadas do modelo de visão. Falaremos sobre frameworks em breve.
Terminamos assim mais uma aula.
Utilize o espaço de comentários para dúvidas, críticas, elogios ou sugestões. É sempre um prazer ler sua opinião sobre meu conteúdo.
Gostaria de agradecer novamente pelos comentários que venho recebendo.
Na próxima aula estudaremos um pouco mais sobre métodos, desta vez o __autoload(), além de conhecermos algumas funções para manipulação de objetos.
quarta-feira, 28 de março de 2012
Curso de PHP Orientado a Objetos - Parte 8
Vamos iniciar o oitavo artigo do curso de PHP Orientado a Objetos do site www.cafeesoftware.com.
Para conhecer as demais partes, clique aqui.
Ao final deste artigo, você será capaz de:
- Entender como se da a relação entre objetos
- Entender quando se dá um relacionamento de associação, agregação e composição
Associação: É a relação mais comum entre dois objetos. Quando acontece? Quando uma classe "usa" outra classe.
Exemplo: Um motorista utiliza (depende do carro, mas este não faz parte do motorista) o carro para trabalhar.
Agregação: É o tipo de relação conhecida como todo/parte. Na agregação o objeto agrega outro objeto, ou seja, torna um objeto externo parte de si.. Assim o objeto pai poderá utilizar funcionalidades do objeto agregado, mas ele não depende dele (agregado) para existir.
Exemplo: A tampa de uma caneta é parte da caneta, se a caneta não tiver a tampa, ela não deixará de ser uma caneta.
Composição: Neste caso, o objeto-pai é responsável pela criação e destruição de suas partes. O objeto-pai realmente "possui" as instâncias de suas partes. Resumidamente, um só existe caso o outro também exista.
Exemplo: O motor de um carro é parte fundamental do carro.
Agora que você já conhece na teoria os tipos de relacionamento, que tal vermos na prática?
Associação
A forma mais comum de associação é quando temos um objeto como atributo de outro. Criaremos um objeto Produto e outro Fornecedor. Onde Fornecedor é um dos atributos de Produto.
Vamos analisar o diagrama UML:
![]() |
| Associação entre Produto e Fornecedor |
Observe que uma das propriedades (Fornecedor), espera receber um objeto do tipo Fornecedor.
Vamos agora criar as duas classes e em seguida os objetos.
class Produto{
public $Id;
public $Nome;
public $Valor;
public $Fornecedor;
public function __construct($Id, $Nome, $Valor, $Fornecedor){
$this->Id = $Id;
$this->Nome = $Nome;
$this->Valor = $Valor;
$this->Fornecedor = $Fornecedor;
}
}
class Fornecedor{
public $Id;
public $RazaoSocial;
public $Endereco;
public $Telefone;
public function __construct($Id, $RazaoSocial, $Endereco, $Telefone){
$this->Id = $Id;
$this->RazaoSocial = $RazaoSocial;
$this->Endereco = $Endereco;
$this->Telefone = $Telefone;
}
}
$fornecedor = new Fornecedor(359, "Mercado da Casa", "Rua B", "3232-2222" );
$produto = new Produto(122, "Café 250g", 2.85, $fornecedor );
echo "Código: " . $produto->Codigo . "< br />";
echo "Produto: " . $produto->Nome . "< br />";
echo "Fornecedor: " . $produto->Fornecedor->RazaoSocial . "< br />";
Perceba que, ao criar o objeto Produto, passamos o objeto Fornecedor, em seguida, para imprimir fizemos uma referenciação de Produto e Fornecedor.
Agregação
Conforme visto anteriormente, esta relação se dá quando temos o "TODO/PARTE".
Uma forma de exemplificar sua implementação e com o clássico exemplo de um carrinho de compras.
Teremos duas classes, produto (bem parecido com a que vimos anteriormente) e a classe Carrinho.
Observe o diagrama:
Importante destacar que a propriedade Itens é um array, poderia ser representando como: Itens[] : Produto.
Observer que a classe Carrinho possui dois métodos, ExibeLista() e o CalculaTotal().
Vamos criar codificar as duas classes e em seguida criar os objetos:
Agregação
Conforme visto anteriormente, esta relação se dá quando temos o "TODO/PARTE".
Uma forma de exemplificar sua implementação e com o clássico exemplo de um carrinho de compras.
Teremos duas classes, produto (bem parecido com a que vimos anteriormente) e a classe Carrinho.
Observe o diagrama:
![]() |
| Relação de Agregação |
Observer que a classe Carrinho possui dois métodos, ExibeLista() e o CalculaTotal().
Vamos criar codificar as duas classes e em seguida criar os objetos:
class Produto{
public $Id;
public $Nome;
public $Valor;
public function __construct($Id, $Nome, $Valor){
$this->Id = $Id;
$this->Nome = $Nome;
$this->Valor = $Valor;
}
}
Agora vamos criar a classe Carrinho:
class Carrinho{
private $itens;
public function InsereProduto(Produto $item){
$this->itens[] = $item;
}
public function ExibeLista(){
foreach( $this->itens as $item ){
return $item->nome."< br />;
}
}
public function CalculaTotal(){
$valor_total = 0;
foreach( $this->itens as $item ){
$valor_total += $item->Valor;
}
echo " R$ " . number_format($valor_total, 2, ',', '.');
}
}
Vamos as explicações: Repare que na linha 5 da classe Carrinho estamos obrigando o $item a ser do tipo Produto. Este é um conceito conhecido como TypeHinting ou "Sugestão de tipo", caso este método receba algo que não seja um Produto, ocasionará um erro.
Na linha 7 estamos inserindo cada produto no array $itens.
O método ExibeLista apenas percorre o array de itens exibindo o nome de cada produto.
O método CalculaTotal percorre o array de itens somando o valor de cada um e em seguida mostrando (formatado) o valor final.
Vamos testar?
Composição
A diferença da composição para a agregação é que quando o objeto "todo" é destruído, suas partes também são, exatamente por terem sido criadas pelo objeto "todo". Podemos dizer que na composição o objeto-pai "possui" as instâncias de suas partes.
Observe a notação para a composição:
Neste exemplo, a classe cliente será responsável por instanciar contato. Vamos agora codificar para entender melhor:
Perceba que a classe Cliente só existe se também existir a classe Contato. Uma aplicação clara da relação de composição. Vamos agora testar o exemplo:
Note que em nenhum momento instanciamos Contato, pois quem faz isso é a classe Cliente, daí a relação de composição.
Finalizamos assim mais um artigo do curso.
Na próxima aula veremos os métodos __set(), __get() e __call() conhecidos como métodos interceptores.
Utilize o espaço de comentários para críticas, sugestões ou elogios.
Na linha 7 estamos inserindo cada produto no array $itens.
O método ExibeLista apenas percorre o array de itens exibindo o nome de cada produto.
O método CalculaTotal percorre o array de itens somando o valor de cada um e em seguida mostrando (formatado) o valor final.
Vamos testar?
$produto1 = new Produto(1, "Milho verde", 1.75); $produto2 = new Produto(2, "Ervilha", 1.65); $produto3 = new Produto(3, "Café 250Gr", 3.45); $produto4 = new Produto(4, "Refrigerante 2L", 3.69); $CarrinhoCompra = new Carrinho(); $CarrinhoCompra->InsereProduto($produto1); $CarrinhoCompra->InsereProduto($produto2); $CarrinhoCompra->InsereProduto($produto3); $CarrinhoCompra->InsereProduto($produto4); $CarrinhoCompra->ExibeLista(); $CarrinhoCompra->CalculaTotal();Ao executar, você perceberá que a lista de itens (nome) será exibida, seguido do valor total.
Composição
A diferença da composição para a agregação é que quando o objeto "todo" é destruído, suas partes também são, exatamente por terem sido criadas pelo objeto "todo". Podemos dizer que na composição o objeto-pai "possui" as instâncias de suas partes.
Observe a notação para a composição:
![]() |
| Relação de Composição |
class Contato{
public $Nome;
public $Email;
public $Telefone;
/* Método setContato()
* Grava informações de contato
*/
public function setContato($Nome, $Email, $Telefone){
$this->Nome = $Nome;
$this->Email = $Email;
$this->Telefone = $Telefone;
}
/* Método EscreveContato()
* Escreve as informações de contato
*/
public function EscreveContato(){
echo "Nome: " . $this->Nome . "< br />";
echo "Email: " . $this->Email . "< br />";
echo "Telefone: " . $this->Telefone . "< br />";
}
}
Agora vamos criar a classe Cliente:class Cliente{
public $Codigo;
public $Endereco;
public $Contato;
/* Método construtor()
* Construtor da classe
*/
public function __construct(){
/* Instancia um novo Contato
* Perceba que isso só é feito
* aqui. Não é feito fora dessa
* classe
*/
$this->Contato = new Contato();
}
/* Método setContato()
* Grava informações de contato
*/
public function setContato($Nome, $Email, $Telefone){
// Chama e envia informações para o objeto Contato
$this->Contato->setContato($Nome, $Email, $Telefone);
}
/* Método EscreveContato()
* Escreve as informações de contato
*/
public function EscreveContato(){
// Chama um método do objeto Contato
$this->Contato->EscreveContato();
}
}
Perceba que a classe Cliente só existe se também existir a classe Contato. Uma aplicação clara da relação de composição. Vamos agora testar o exemplo:
$leandro = new Cliente();
$leandro->Codigo = 7;
$leandro->setContato("Leandro","leandrocastro@gmail.com","(33) 3333-3333");
$leandro->Endereco = "Rua 13 de maio";
$leandro->EscreveContato();
echo "Endereço: " . $leandro->Endereco;
Note que em nenhum momento instanciamos Contato, pois quem faz isso é a classe Cliente, daí a relação de composição.
Finalizamos assim mais um artigo do curso.
Na próxima aula veremos os métodos __set(), __get() e __call() conhecidos como métodos interceptores.
Utilize o espaço de comentários para críticas, sugestões ou elogios.
terça-feira, 27 de março de 2012
Curso de PHP Orientado a Objetos - Parte 7
![]() |
| imagem meramente ilustrativa |
Ao final deste artigo, você será capaz de:
- Entender o conceito de constantes na POO;
- Entender o conceito de propriedades estáticas;
- Entender o conceito de métodos estáticos.
As classes permitem armazenar valores de duas formas: constantes de classe e propriedades estáticas. Estes atributos são comuns em todos os objetos da mesma classe.
Constantes
Primeiro vamos definir o que é constante.
Uma constante é exatamente o oposto de uma variável, ou seja, algo que mantém seu valor até o final do script (salvo alguma exceções). Geralmente definimos uma constante perto do início do código ou em uma função.
A declaração de constantes é feita através da palavra-chave const. Para acessar constantes de classe fora do escopo dela, a seguinte notação é utilizada NomeClasse::Constante; e já dentro da classe, utilizamos a notação self::Constante. A palavra-chave self também pode ser utilizada para referenciar a própria classe.
Vamos analisar:
/* Vamos declarar uma
* constante chamada pi
*/
class Funcoes{
const Pi = 3.14;
}
/* Vamos herdar Funcoes
* e criar outra constante
*/
class Aplicacao extends Funcoes{
const Versao = 3.8;
function __construct($Nome){
echo $Nome. "< br/>";
echo self::Versao . "< br />";
echo parent::Pi . "< br />";
echo Funcoes::Pi . "< br />";
}
}
$sistema1 = new Aplicacao("CafeeSoftware");
Perceba que acessamos a constante Pi tanto pela sintaxe: Funcoes::Pi, quanto pela sintaxe: parent::Pi.
Lembre-se que parent se refere a classe-pai. E Pi é da classe-pai de Aplicação. Self refere-se a classe em questão.
Propriedades e métodos estáticos
Podemos considerar que propriedades e métodos estáticos podem ser acessados sem a necessidade de instanciar um objeto. Utilizamos este recurso quando, por exemplo, temos um método que é acessado diversas vezes na mesma aplicação, e queremos economizar algumas linhas de código a fim de não ter que criar um objeto a todo momento. É importante destacar que um método estático não pode fazer referencia a propriedades internas pelo operador $this, pois este operador é usado para referenciar instâncias da classe ou seja, objetos.
Utilizamos a palavra chave static para definir a declaração de membros estáticos.
Vamos ao exemplo:
Membros estáticos também podem ser acessados internamente utilizando o operador self (o mesmo que vimos anteriormente), veja:
Quando se tratar de uma subclasse herdando propriedades ou mesmo métodos estáticos, a referência é feita normalmente através da palavra reservada parent, como já vimos anteriormente.
No próximo artigo estudaremos os relacionamentos: Composição, agregação e associação. Veremos na prática quando ocorre cada um deles e sua utilização no PHP.
Utilize o espaço de comentários para dúvidas, sugestões e elogios.
Até a próxima.
Lembre-se que parent se refere a classe-pai. E Pi é da classe-pai de Aplicação. Self refere-se a classe em questão.
Propriedades e métodos estáticos
Podemos considerar que propriedades e métodos estáticos podem ser acessados sem a necessidade de instanciar um objeto. Utilizamos este recurso quando, por exemplo, temos um método que é acessado diversas vezes na mesma aplicação, e queremos economizar algumas linhas de código a fim de não ter que criar um objeto a todo momento. É importante destacar que um método estático não pode fazer referencia a propriedades internas pelo operador $this, pois este operador é usado para referenciar instâncias da classe ou seja, objetos.
Utilizamos a palavra chave static para definir a declaração de membros estáticos.
Vamos ao exemplo:
class Teste{
public static $propriedade = "Esta é uma propriedade estática";
public static function MetodoEstatico(){
echo "Este é um método estático";
}
}
/* Para acessar é simples,
* perceba que não é necessário
* criar o objeto.
*/
echo Teste::$propriedade;
//Agora o método
Teste::MetodoEstatico();
Membros estáticos também podem ser acessados internamente utilizando o operador self (o mesmo que vimos anteriormente), veja:
class Teste{
public static $propriedade = "www.cafeesoftware.com - Transformando Café em Software";
public static function RetornaPropriedade(){
return self::propriedade;
}
public static function UsarMetodoRetorna(){
return self::RetornaPropriedade();
}
}
// Para acessar:
echo Teste::RetornaPropriedade();
Teste::UsarMetodoRetorna();
Quando se tratar de uma subclasse herdando propriedades ou mesmo métodos estáticos, a referência é feita normalmente através da palavra reservada parent, como já vimos anteriormente.
No próximo artigo estudaremos os relacionamentos: Composição, agregação e associação. Veremos na prática quando ocorre cada um deles e sua utilização no PHP.
Utilize o espaço de comentários para dúvidas, sugestões e elogios.
Até a próxima.
segunda-feira, 26 de março de 2012
Novidades!
Ainda está semana o Café e Software irá mudar seu layout e mais, teremos um servidor próprio. Cortesia de um ilustre visitante do blog.
Não deixe de acompanhar!
Curso de PHP Orientado a Objetos - Parte 6
Vamos começar a semana com o sexto artigo do Curso de PHP Orientado a Objetos.
Para conhecer as demais partes, clique aqui.
Ao final deste artigo, você será capaz de:
- Entender o significado do encapsulamento para a POO;
- Entender e aplicar a visibilidade dos métodos e propriedades.
Encapsulamento
É um dos recursos mais interessantes que a programação orientada a objetos nos fornece. Trata-se de um mecanismo que provê proteção de acesso aos membros internos de um objeto.
Alguns métodos e propriedades devem ser só de responsabilidade da classe-pai. Sem os modificadores de acesso, ela perde esta responsabilidade, fazendo com que outras classes tenham acesso a estes métodos e propriedades.
Para atingir o encapsulamento, uma das formas é definindo a visibilidade das propriedades e dos métodos de um objeto. A visibilidade define a forma como essas propriedades devem ser acessadas. Existem três formas de acesso:
- private: Este modificador não permite ser acessado por classes descendentes (classes-filhas), só pode ser acessado dentro da própria classe.
- public: Este modificador é o default (padrão), ou seja, quando um método não tiver um modificador de visibilidade definido, ele sempre será public. Public significa que o método ou propriedade em questão pode ser acessado por todas as outras classes e métodos sem quaisquer restrições.
- protected: Pode ser acessado apenas por métodos da própria classe e classes filhas.
Podemos dizer que o encapsulamento nos permite "ocultar" tudo aquilo que não é "importante", ou seja, detalhes internos do funcionamento da classe são ocultos para os objetos. O objeto só conhece o que é necessário, o que ele não precisa saber/conhecer, fica oculto (a nível de objeto).
Private
Até agora, nos artigos anteriores, declaramos classes como public e não definimos visibilidades dos métodos. Vamos iniciar com um exemplo prático, para facilitar a compreensão.
A proposta é criar uma classe chamada Fornecedor e marcaremos algumas das propriedades como private. Dessa forma, os elementos private só poderão ser alterados por métodos da mesma classe. Deixaremos para livre acesso, o nome e o valor, marcado como public.
class Fornecedor{
private $Id; //identificação
public $Nome; //nome do produto
private $Compra; //valor de compra
public $Valor; //valor de venda
}
Observe a imagem abaixo:
Criamos o objeto Fornecedor e ao definir as propriedades, o próprio Eclipse, através de sua função autocomplete, carregará somente as funções públicas (public). Perceba que ele não exibe na lista as funções privadas (private).
Se mesmo assim você tentar algo como:
Ok, mas como faço para atribuir algo a essa propriedade caso necessário?
Se você fez essa pergunta, parabéns!
Para atribuir algo, basta criar um método pertencente a classe Fornecedor que manipule estas propriedades. Que tal chamarmos de "Set" para definir e "Get" para obter o conteúdo dos atributos?
Veja o exemplo:
Agora que criamos o método get e set para a propriedade $Compra, é possível realizar a chamada normalmente:
O interessante neste caso, é perceber que para um determinado valor chegar a propriedade $Compra, ele deve passar pelo método setCompra. Isso nos traz um controle maior sobre a aplicação visto que, você pode realizar várias operações antes da chagada do valor, neste caso perceba que no método setCompra, checamos se o valor é um número (is_numeric) e se é maior que zero.
Poderíamos criar um set e um get para mais elementos definidos como private mas cuidado, utilize os Getters e Setters somente quando existe a real necessidade, variáveis internas ou que não precisam de nenhum tipo de verificação ou tratamento, não utilize.
Prefira sempre utilizar métodos Getter e Setters ao invés de um campo público (public) mas lembre-se, simplificar é a alma da POO, criar dezenas de métodos não simplifica.
Protected
Vimos no exemplo anterior, o uso do parâmetro de visibilidade private. Vale ressaltar que quando uma propriedade é definida como private, ela não pode ser sobrescrita por classes filhas, ou seja, uma classe filha não consegue chamar os métodos setters e getters da classe pai (no caso do atributo estar como private).
Caso você tenha uma classe Funcionário com o método setSalario e o atributo Salário do tipo private, e crie a subclasse Estagiário, você não consegue chamar o método mesmo fazendo uso da herança, está é uma característica do private.
Em outras palavras, se um atributo é do tipo private, ele só funciona na classe que foi declarado, caso você queira fazer uso do mesmo em outras classes (filhas) é necessário modificar o tipo para Protected.
Veja:
![]() |
| Eclipse exibindo apenas as propriedades públicas da classe Fornecedor |
Se mesmo assim você tentar algo como:
$empresa1 = new Fornecedor(); $empresa1->Compra = 400;Será retornado uma mensagem de erro, pois a propriedade Compra é privada (private).
Ok, mas como faço para atribuir algo a essa propriedade caso necessário?
Se você fez essa pergunta, parabéns!
Para atribuir algo, basta criar um método pertencente a classe Fornecedor que manipule estas propriedades. Que tal chamarmos de "Set" para definir e "Get" para obter o conteúdo dos atributos?
Veja o exemplo:
class Fornecedor{
private $Id; //identificação
public $Nome; //nome do produto
private $Compra; //valor de compra
public $Valor; //valor de venda
/* Olha o método setCompra()
* que vai definir um valor para
* a propriedade $Compra
*/
public function setCompra($Compra){
if (is_numeric($Compra) && $compra > 0)
{
$this->Compra = $Compra;
}
}
/* Vamos agora criar o método
* getCompra que vai retornar
* o conteúdo da propriedade $compra
*/
public function getCompra(){
return $this->Compra;
}
}
Agora que criamos o método get e set para a propriedade $Compra, é possível realizar a chamada normalmente:
$empresa1 = new Fornecedor(); $empresa1->Nome = "Vale"; $empresa1->setCompra(400); echo "O valor do produto ".$empresa1->Nome." é de ".$empresa1->getCompra();
O interessante neste caso, é perceber que para um determinado valor chegar a propriedade $Compra, ele deve passar pelo método setCompra. Isso nos traz um controle maior sobre a aplicação visto que, você pode realizar várias operações antes da chagada do valor, neste caso perceba que no método setCompra, checamos se o valor é um número (is_numeric) e se é maior que zero.
Poderíamos criar um set e um get para mais elementos definidos como private mas cuidado, utilize os Getters e Setters somente quando existe a real necessidade, variáveis internas ou que não precisam de nenhum tipo de verificação ou tratamento, não utilize.
Prefira sempre utilizar métodos Getter e Setters ao invés de um campo público (public) mas lembre-se, simplificar é a alma da POO, criar dezenas de métodos não simplifica.
Protected
Vimos no exemplo anterior, o uso do parâmetro de visibilidade private. Vale ressaltar que quando uma propriedade é definida como private, ela não pode ser sobrescrita por classes filhas, ou seja, uma classe filha não consegue chamar os métodos setters e getters da classe pai (no caso do atributo estar como private).
Caso você tenha uma classe Funcionário com o método setSalario e o atributo Salário do tipo private, e crie a subclasse Estagiário, você não consegue chamar o método mesmo fazendo uso da herança, está é uma característica do private.
Em outras palavras, se um atributo é do tipo private, ele só funciona na classe que foi declarado, caso você queira fazer uso do mesmo em outras classes (filhas) é necessário modificar o tipo para Protected.
Veja:
class Funcionario{
private $Id;
private $Nome;
private $Nascimento;
private $Salario;
function setSalario($Salario){
if (is_numeric($Salario) && $Salario > 0)
{
$this->Salario = $Salario;
}
}
function getSalario(){
return $this->Salario;
}
}
Agora, vamos criar a classe Estagiário, que será uma subclasse de Funcionário.
class Estagiario extends Funcionario {
/* Método getSalario será
* sobrescrito pois o estagiário
* neste modelo possui um bônus
* de 10%
*/
function getSalario(){
return $this->Salario * 1.10;
}
}
Depois das duas classes criadas, vamos criar o objeto estagiário:
$junior = new Estagiario; $junior->setSalario(300); echo "O salario é: ".$junior->getSalario;
Essa ação resultaria em um erro. Isso ocorre porque a propriedade $Salario é uma propriedade private, o que significa que ela somente pode ser acessada de dentro da classe em que ela foi declarada, neste caso, a classe Funcionário.
Para que as subclasses consigam acessar uma propriedade da classe pai, definimos como protected.
Exemplo:
class Funcionario{
private $Id;
private $Nome;
private $Nascimento;
protected $Salario;
function setSalario($Salario){
if (is_numeric($Salario) && $Salario > 0)
{
$this->Salario = $Salario;
}
}
function getSalario(){
return $this->Salario;
}
}
Agora podemos criar a classe Estagiário da mesma forma que fizemos no exemplo anterior e em seguida criar o objeto:
$junior = new Estagiario; $junior->setSalario(300); echo "O salario é: ".$junior->getSalario;
Com essa pequena modificação, tornamos o atributo $Salario "extensível" a todas as classes que forem criadas a partir da classe Funcionário. Este exemplo não retornaria erro.
Public
Explicar o comportamento do modificador de acesso public é simples, pois é a propriedade padrão do PHP. Basicamente, quando não é definido a visibilidade, ela será pública ou seja, você pode modificar, herdar ou atribuir sem nenhum impedimento, não é necessário os métodos Getters e Setters para propriedades públicas.
Terminamos aqui mais um artigo.
No próximo veremos constantes e propriedades estáticas.
Utilize o espaço de comentários para dúvidas, sugestões e elogios.
Ps.: Venho recebendo alguns comentários que tem servido de estímulo para a continuação desta série. Muito obrigado!
sexta-feira, 23 de março de 2012
Curso de PHP Orientado a Objetos - Parte 5
Este é quinto artigo do Curso de PHP Orientado a Objetos.
Métodos abstratos possuem uma definição semelhante, não podem ser implementados nas classes abstratas, deve ser definido somente a assinatura do método e deve obrigatoriamente, ser implementado na integra pela classe filha que o estender. Em suma, um método abstrato é definido em uma classe abstrata, mas deve conter somente sua assinatura, o "corpo" do método fica por conta das classes filhas.
Estamos levando para o mundo OO uma definição que temos no mundo real, veja: Um cachorro, um gato, um cavalo são animais, cada um com suas características especificas, mas todos são animais, todos possuem nome, idade e falam. Não faria sentido criar o objeto Animal.
Se tentarmos instanciar a classe animal teríamos o seguinte erro:
Fatal error: cannot instantiate abstract class Animal in animal.class.php on line 5
Para conhecer as demais partes, clique aqui.
Ao final deste artigo, você será capaz de:
- Entender o conceito de Abstração
- Criar Classes Abstratas
- Criar Classes Finais
- Criar Métodos Abstratos
- Criar Métodos Finais
Abstração
Podemos considerar abstração uma forma de separar mentalmente, simplificar ou mesmo considerar isoladamente. Um sistema orientado a objetos não deve ser visto como uma única peça, devamos separá-lo em partes, concentrando nas peças mais importantes e ignorando os detalhes (em primeiro momento) para que possamos construir peças bem-definidas que possam ser reaproveitadas mais tarde, formando uma estrutura hierárquica.
Sempre que estiver desenvolvendo um sistema OO, você deve aplicar este conceito, abstraia ao máximo, concentre-se em separar o sistema em módulos.
Classes Abstratas e Métodos Abstratos
Seguindo o conceito de abstração que acabamos de expor, encontraremos classes que irão servir como classes estruturais ou seja, que estão na nossa hierarquia de classes para servirem de base para outras classes, mas que nunca serão instanciadas em objetos, somente suas filhas. Neste contexto, é interessante definir está classe como abstrata, de modo que ninguém consiga instancia-la.
A grosso modo, classe abstrata nada mais é do que um modelo comum, que deve ser seguido pelas classes filhas, nunca é instanciado em objeto ou seja, não existe isoladamente.
Métodos abstratos possuem uma definição semelhante, não podem ser implementados nas classes abstratas, deve ser definido somente a assinatura do método e deve obrigatoriamente, ser implementado na integra pela classe filha que o estender. Em suma, um método abstrato é definido em uma classe abstrata, mas deve conter somente sua assinatura, o "corpo" do método fica por conta das classes filhas.
Com exemplo fica ainda mais fácil de entender:
/*Definimos uma classe como abstrata
* utilizando a palavra reservada abstract
* antes da palavra class
*/
abstract class Animal
{
public $nome;
public $idade;
//O método construtor seta os dois atributos
function __construct($nome, $idade)
{
$this->nome = $nome;
$this->idade = $idade;
}
//O método descrição retorna o nome e a idade
public function Descricao()
{
return $this->nome . ", " . $this->idade . " anos de idade";
}
/*O método Falar deve
*ser implementado na classe filha
*perceba que ele não tem implementação
*/
abstract public function Falar();
}
Temos nessa classe todas as características comuns de um animal. Todo animal possui um nome e todo animal possui uma idade, todo animal fala (o cachorro faz Au Au, o gato faz Miau). Perceba que o método Falar não possui nada implementado, além disso, a definição do método é precedida pela palavra abstract, o que significa que o método deve ser implementado em TODAS as classes que estenderem a classe Animal.Estamos levando para o mundo OO uma definição que temos no mundo real, veja: Um cachorro, um gato, um cavalo são animais, cada um com suas características especificas, mas todos são animais, todos possuem nome, idade e falam. Não faria sentido criar o objeto Animal.
Se tentarmos instanciar a classe animal teríamos o seguinte erro:
Fatal error: cannot instantiate abstract class Animal in animal.class.php on line 5
Obviamente agora temos que criar uma subclasse de Animal, chamaremos de Cachorro.
Agora podemos instanciar a classe Cachorro sem problemas:
Da mesma forma que criamos a classe Cachorro, poderíamos criar a classe Gato, Cavalo, Pato, todas herdando da classe Animal.
Classes Finais
Classes finais podem ser definidas como classes que não podem ser estendidas ou seja, não pode ser uma superclasse.
Uma classe é definida como final quando colocamos a palavra reservada final antes da palavra class.
A classe cachorro definida aqui, não pode ser herdada por nenhuma outra classe.
Métodos finais
Assim como classes finais, um método final não pode ser estendido e obviamente não pode ser abstrato, pois métodos abstratos foram feitos para serem estendidos e declarados na classe filha.
Para declarar um método como final basta usar a palavra reservada final antes da palavra function.
Terminamos assim mais um módulo do curso.
No próximo artigo falaremos sobre o encapsulamento.
Utilize o espaço de comentários para tirar suas dúvidas.
// Herdamos a classe Animal
class Cachorro extends Animal
{
/* Somos obrigados a implementar
* o método falar
*/
public function Falar()
{
return "Au Au!";
}
/* Vamos também complementar
* o método Descricao
*/
public function Descricao()
{
return parent::Descricao() . ", eu sou um cachorro!";
}
}
Agora podemos instanciar a classe Cachorro sem problemas:
$animal = new Cachorro("Rex", 5);
echo $animal->Descricao();
echo $animal->Falar();
Da mesma forma que criamos a classe Cachorro, poderíamos criar a classe Gato, Cavalo, Pato, todas herdando da classe Animal.
Classes Finais
Classes finais podem ser definidas como classes que não podem ser estendidas ou seja, não pode ser uma superclasse.
Uma classe é definida como final quando colocamos a palavra reservada final antes da palavra class.
final class Cachorro
{
public $nome;
public $idade;
function __construct($nome, $idade)
{
$this->nome = $nome;
$this->idade = $idade;
}
public function Descricao()
{
return $this->nome . ", " . $this->idade . " anos de idade";
}
}
A classe cachorro definida aqui, não pode ser herdada por nenhuma outra classe.
Métodos finais
Assim como classes finais, um método final não pode ser estendido e obviamente não pode ser abstrato, pois métodos abstratos foram feitos para serem estendidos e declarados na classe filha.
Para declarar um método como final basta usar a palavra reservada final antes da palavra function.
Class Cachorro
{
public $nome;
public $idade;
/* Este método não pode
* se estendido (sobrescrito)
*/
final function Descricao()
{
return $this->nome . ", " . $this->idade . " anos de idade";
}
}
Terminamos assim mais um módulo do curso.
No próximo artigo falaremos sobre o encapsulamento.
Utilize o espaço de comentários para tirar suas dúvidas.
Marcadores:
Classes,
Classes Abstratas,
Classes Finais,
Métodos Abstratos,
Métodos finais,
OO,
Orientação a Objetos,
Orientado a Objetos,
PHP OO,
PHP Orientado a Objetos
quinta-feira, 22 de março de 2012
Curso de PHP Orientado a Objetos - Parte 4
Este é o quarto artigo do curso de PHP Orientado a Objetos.
Para conhecer as demais partes clique aqui.
Ao final deste artigo, você será capaz de:
Agora vamos modelar a classe ChequeEspecial, que vai herdar a classe Cheque:
Agora vamos testar o exemplo:
Temos ai um exemplo claro do polimorfismo, onde ChequeEspecial herdou todas as características da classe cheque, entretanto o que difere as duas classes é a ocorrência do polimorfismo nos métodos TipoCheque() e CalculaJuros().
Perceba que a classe ChequeEspecial sobrescreveu o método CalcularJuros da classe-pai e mudou seu comportamento. O método calcular juros nos dois tipos de cheque é igual, o que difere é o comportamento deles.
É importante notar também que a classe ChequeEspecial herdou o método construtor da classe-pai, para setar o atributo $Valor.
No foreach estamos apenas percorrendo o Array de objetos.
Terminamos assim mais um conteúdo do curso. No próximo artigo falaremos sobre Classes Abstratas, Classes Finais, Métodos Abstratos e Métodos Finais.
Utilize o espaço de comentários para tirar suas dúvidas.
Para conhecer as demais partes clique aqui.
Ao final deste artigo, você será capaz de:
- Entender e aplicar o conceito do polimorfismo
Polimorfismo
Polimorfismo é sempre um gargalo no ensino da POO. Sei, pela dificuldade que meus alunos encontram ao tentar compreender este conceito através de livros ou manuais que, em sua maioria, contemplam exemplos complexos com uma linguagem confusa ou técnica de mais.
Tentarei expor neste artigo, o conceito e a aplicabilidade do polimorfismo em sua forma mais simples, evitando o over engineering sobre o assunto.
O polimorfismo significa muitas formas ou algo que pode mudar sua forma. Em termos de programação, polimorfismo pode ser entendido como um único nome de classe ou métodos que represente um código diferente.
Lembre-se: mesmo nome, porém código diferente.
Vantagens:
- O polimorfismo facilita a reutilização de código.
- Facilita a manutenção, visto que não é preciso utilizar várias estruturas condicionais para simular situações diferentes.
Para entender, vamos utilizar o clássico exemplo do banco, que tem 2 tipos de cheques: Cheque Comum e o Cheque Especial.
Ambos os cheques possuem a mesma estrutura, porém um cobra 20% de juros (comum) e o outro cobra 10 % (especial).
Vamos modelar inicialmente a classe Cheque:
class Cheque{
public $Valor;
/* Método Construtor
* Recebe o parâmetro $Valor.
*/
function __construct($Valor){
$this->Valor = $Valor;
}
/* Método CalcularJuros()
* Calcula os Juros, neste caso 20%
*/
function CalcularJuros(){
return $this->Valor * 1.20;
}
/* Método TipoCheque()
* Retorna o tipo do Cheque
*/
function TipoCheque(){
return "Comum";
}
}
Estrutura básica, caso você tenha dúvidas com relação ao código, consulte as aulas anteriores.Agora vamos modelar a classe ChequeEspecial, que vai herdar a classe Cheque:
/* Perceba a herança acontecendo
* definida pela palavra extends
*/
class ChequeEspecial extends Cheque{
/* Método CalcularJuros() - Opa!! Mas esse método já não tinha sido
* implementado na classe anterior? Sim, está aí o polimorfismo.
* O juros do Cheque especial é 10%, não 20 como o anterior
*/
function CalcularJuros(){
//Perceba que herdamos a propriedade Valor da classe pai
return $this->Valor * 1.10;
}
/* Método TipoCheque() - Também Sobrescrito
* uso explicito do polimorfismo
*/
function TipoCheque(){
return "Especial";
}
}
Agora vamos testar o exemplo:
//Incluimos as duas classes
require_once("Cheque.class.php");
require_once("ChequeEspecial.class.php");
// Criação dos cheques
$Cheques[1] = new Cheque(380.00);
$Cheques[2] = new ChequeEspecial(600.00);
$Cheques[3] = new Cheque(230.00);
// Percorrendo os Cheques
foreach ( $Cheques as $key => $Cheque )
{
echo "Cheque $key ( {$Cheque->TipoCheque()} )
com juros: R$ {$Cheque->CalcularJuros()} <br /> ";
}
Temos ai um exemplo claro do polimorfismo, onde ChequeEspecial herdou todas as características da classe cheque, entretanto o que difere as duas classes é a ocorrência do polimorfismo nos métodos TipoCheque() e CalculaJuros().
Perceba que a classe ChequeEspecial sobrescreveu o método CalcularJuros da classe-pai e mudou seu comportamento. O método calcular juros nos dois tipos de cheque é igual, o que difere é o comportamento deles.
É importante notar também que a classe ChequeEspecial herdou o método construtor da classe-pai, para setar o atributo $Valor.
No foreach estamos apenas percorrendo o Array de objetos.
Terminamos assim mais um conteúdo do curso. No próximo artigo falaremos sobre Classes Abstratas, Classes Finais, Métodos Abstratos e Métodos Finais.
Utilize o espaço de comentários para tirar suas dúvidas.
Marcadores:
Classes,
Curso de PHP Orientado a Objetos,
Destrutor,
herança,
Métodos,
Orientação a Objetos,
Orientado a Objetos,
PHP OO,
PHP Orientado a Objetos,
polimorfismo,
POO,
Programação Orientada a Objetos
quarta-feira, 21 de março de 2012
Curso de PHP Orientado a Objetos - Parte 3
Esta é a terceira parte do Curso de Php Orientado a Objetos.
Clique aqui para conhecer as partes anteriores.
Ao final deste artigo, você será capaz de:
Caso você tenha dúvidas quanto a esta classe, consulte as aulas anteriores.
Agora vamos criar a classe Funcionário, que irá herdar da classe Pessoa, fique atendo aos comentários e não se preocupe caso não entenda alguma parte do código, iremos explicar detalhadamente em seguida:
Testando nosso exemplo de herança:
Nesta linha estamos adicionando a classe pessoa ao documento, levando em consideração que a classe pessoa está em outro arquivo.
Nesta linha estamos dizendo que a classe Funcionário herdará todas as características de Pessoa. Desta forma, Pessoa será a superclasse, enquanto Funcionário, a subclasse de Pessoa.
Nesta parte declaramos as propriedades do Funcionário. Mas funcionário não teria que ter um nome? Deixamos de criar a propriedade nome pois ela já está criada na classe Pessoa, consequentemente a classe Funcionário herdou essa propriedade, sendo assim, não é necessário cria-la novamente.
Continuando:
Esta parte também é importante, perceba que o método EscreveDados existe na classe pai (volte e verifique) mas foi sobrescrito, e acrescentamos a impressão dos campos de salário, cargo e diadepagamento. Neste caso, será impresso todos os atributos contidos na classe pai (parent::) no método EscreveDados, e também os atributos do método EscreveDados da classe filha, ou seja, um complemento do método pai.
Vale lembrar que o PHP não suporta herança múltipla, isso pode ser feito com o uso de interfaces (veremos no futuro).
Conclusão:
Com este recurso, expandimos nosso código, sem reescreve-lo, isso é extremamente comum quando se trata de criar novas funcionalidades em um software.
Cabe a você estudar e aplicar os conceitos que aprendeu aqui.
Utilize o espaço de comentários para tirar suas dúvidas.
No próximo artigo, veremos o polimorfismo (de forma descomplicada).
Até la!
Clique aqui para conhecer as partes anteriores.
Ao final deste artigo, você será capaz de:
- Entender e aplicar o conceito de herança
Herança
Assim como no mundo real, a palavra se refere ao conceito de receber algo, herança aqui pode ser entendida como um mecanismo que permite construir uma nova classe com base em uma classe previamente existente, em que a nova herda automaticamente todos os atributos, comportamentos e implementações da classe-pai.
Quando se trata de herança, estamos falando de um dos maiores benefícios da Orientação a Objetos, além da capacidade de encapsulamento (essa veremos a seguir, por enquanto, trate o encapsulamento como algo importante). Com a herança, podemos reutilizar partes de código já definidas, além da agilidade, ela elimina a necessidade de duplicar ou rescrever certo código. Essas características nos permitem ao invés de escrevermos uma estrutura totalmente nova, reaproveitar a estrutura existente mesmo que a mesma nos forneça apenas uma base abstrata para o desenvolvimento.
Para estender uma nova classe (chamaremos de subclasse), utilizamos a palavra reservada extends.
Quando criamos uma subclasse, todos os métodos pertencentes a classe pai podem ser executados. Também é possível sobrescrever os seus métodos e propriedades, a fim de criar novos, com outras características. Se na subclasse é escrito um método com o mesmo nome do método existente na classe pai, passa a vigorar o método da classe filha (subclasse).
Para acessar os métodos sobrescritos ou membros estáticos da classe pai, utilizamos a palavra reservada parent.
É importante destacar que somente os métodos protect e public podem ser reescritos (veremos detalhes sobre isso mais a frente).
Nada melhor que um exemplo para facilitar o entendimento por isso, vamos retornar a nossa classe pessoa e a partir dela criaremos a classe funcionário, pois o funcionário é uma pessoa, consequentemente, funcionário herdará as características da classe pessoa, ao invés de duplicarmos tudo de novo na classe funcionário.
class Pessoa{
public $Nome;
public $AnoDeNascimento;
public $Endereco;
public $Telefone;
/* Método Construtor
* Inicializa as propriedades
*/
function __construct($Nome, $AnoDeNascimento, $Endereco, $Telefone){
$this->Nome = $Nome;
$this->AnoDeNascimento = $AnoDeNascimento;
$this->Endereco = $Endereco;
$this->Telefone = $Telefone;
}
/* Método EscreveDados()
* Retorna os dados da Pessoa
*/
function EscreveDados(){
echo "Nome: {$this->Nome}
Ano de nascimento: {$this->AnoDeNascimento}
Endereço: {$this->Endereco}
Telefone: {$this->Telefone}";
}
/* Método ObterIdade()
* Retorna a idade
*/
function ObterIdade(){
$ano_atual = date("Y",time());
return $ano_atual - $this->AnoDeNascimento;
}
}
Caso você tenha dúvidas quanto a esta classe, consulte as aulas anteriores.
Agora vamos criar a classe Funcionário, que irá herdar da classe Pessoa, fique atendo aos comentários e não se preocupe caso não entenda alguma parte do código, iremos explicar detalhadamente em seguida:
require_once("Pessoa.class.php");
class Funcionario extends Pessoa{
public $Salario;
public $Cargo;
public $DiaPagamento;
/* Método Construtor
* Inicializa as propriedades
*/
function __construct($Nome, $AnoDeNascimento, $Endereco, $Telefone, $Salario, $Cargo, $DiaPagamento){
// Chamada do método do construtor da classe-pai
parent::__construct($Nome, $AnoDeNascimento, $Endereco, $Telefone);
// Inicializa as variáveis/propriedades locais da Classe
$this->Salario = $Salario;
$this->Cargo = $Cargo;
$this->DiaPagamento = $DiaPagamento;
}
/* Método EscreverSalario
* Escreve o salário do funcionário
*/
function EscreverSalario(){
echo "Salário: {$this->$Salario}
";
}
/* Método EscreveDados()
* Este método sobrescreve o método EscreveDados() da classe-pai
*/
function EscreveDados(){
parent::EscreveDados();
echo "Salário: {$this->Salario}
Cargo: {$this->Cargo}
Dia de pagamento: {$this->DiaPagamento} ";
}
}
Testando nosso exemplo de herança:
require_once("Funcionario.class.php");
$leandro = new Funcionario("Leandro Castro", 1985, "Rua das Flores 33 - Juiz de fora","(32) 3232-3535", 4.000, "Desenvolvedor Java/PHP", 8);
echo $leandro->ObterIdade();
$leandro->EscreveDados();
Para um melhor entendimento, você deve colocar em prática os exemplos, analisar e estuda-los.
Vamos começar analisando a classe Funcionário:
Vamos começar analisando a classe Funcionário:
require_once("Pessoa.class.php");
Nesta linha estamos adicionando a classe pessoa ao documento, levando em consideração que a classe pessoa está em outro arquivo.
class Funcionario extends Pessoa{
Nesta linha estamos dizendo que a classe Funcionário herdará todas as características de Pessoa. Desta forma, Pessoa será a superclasse, enquanto Funcionário, a subclasse de Pessoa.
public $Salario; public $Cargo; public $DiaPagamento;
Nesta parte declaramos as propriedades do Funcionário. Mas funcionário não teria que ter um nome? Deixamos de criar a propriedade nome pois ela já está criada na classe Pessoa, consequentemente a classe Funcionário herdou essa propriedade, sendo assim, não é necessário cria-la novamente.
Continuando:
function __construct($Nome, $AnoDeNascimento, $Endereco, $Telefone, $Salario, $Cargo, $DiaPagamento){
// Chamada do método do construtor da classe-pai
parent::__construct($Nome, $AnoDeNascimento, $Endereco, $Telefone);
Se você achou esta parte complicada, fique tranquilo, é mais simples do que parece.
Lembra que estamos trabalhando na classe Funcionário, que é uma subclasse de Pessoa, com isso, Funcionário possui todos os métodos de Pessoa. Vimos que o construtor também é um método, executado quando criamos o objeto e neste caso, estamos sobrescrevendo este construtor.
A linha 4 retrata exatamente isso, estamos dizendo que o pai (parent::) que irá receber os dados (nome, anodenascimento, endereco e telefone) e a classe Funcionário que ficará responsável pelos demais dados (salario, cargo e diadepagamento).
Se não declarássemos o método construtor na classe Funcionário, seria usado o da classe pai, ou seja, o método construtor de Pessoa.
function EscreverSalario(){
echo "Salário: {$this->$Salario}
";
}
Se você esta estudando com atenção, percebeu que este método foi uma nova implementação, ele não exsite na classe pai, pois além de herdar, você pode criar novos métodos e propriedades.function EscreveDados(){
parent::EscreveDados();
echo "Salário: {$this->Salario}
Cargo: {$this->Cargo}
Dia de pagamento: {$this->DiaPagamento} ";
}
Esta parte também é importante, perceba que o método EscreveDados existe na classe pai (volte e verifique) mas foi sobrescrito, e acrescentamos a impressão dos campos de salário, cargo e diadepagamento. Neste caso, será impresso todos os atributos contidos na classe pai (parent::) no método EscreveDados, e também os atributos do método EscreveDados da classe filha, ou seja, um complemento do método pai.
Vale lembrar que o PHP não suporta herança múltipla, isso pode ser feito com o uso de interfaces (veremos no futuro).
Conclusão:
Com este recurso, expandimos nosso código, sem reescreve-lo, isso é extremamente comum quando se trata de criar novas funcionalidades em um software.
Cabe a você estudar e aplicar os conceitos que aprendeu aqui.
Utilize o espaço de comentários para tirar suas dúvidas.
No próximo artigo, veremos o polimorfismo (de forma descomplicada).
Até la!
Marcadores:
Classes,
Construtor,
Curso de PHP Orientado a Objetos,
Destrutor,
herança,
Métodos,
OO,
Orientação a Objetos,
Orientado a Objetos,
PHP OO,
PHP Orientado a Objetos,
POO,
Programação Orientada a Objetos
segunda-feira, 19 de março de 2012
Curso de PHP Orientado a Objetos - Parte 2
Dando continuidade a nosso curso.
Esta é a segunda parte do curso de PHP Orientado a Objetos.
Clique aqui para conhecer a primeira parte.
Ao final deste artigo, você será capaz de:
Agora vamos criar uma instância de pessoa:
Agora vamos preencher seus atributos:
Podemos verificar os valores inseridos da seguinte forma:
Agora vamos criar um método para a classe Pessoa, que trabalhará com as propriedades do objeto. O método terá o nome MostrarPessoa() e basicamente servirá para mostrar os dados do objeto.
Lembre-se que método age dentro do escopo da classe.
Classe alterada:
Temos um novo conceito apresentado aqui. Trata-se da pseudo-variável $this, que serve basicamente para diferenciar as propriedades do objeto de variáveis locais. Lembre-se, $this referencia o objeto ATUAL e acessa suas propriedades.
Agora vamos novamente reescrever o objeto Pessoa executando o método MostrarPessoa():
Quando o método for executado, todos os dados do objeto P1 serão mostrados na tela.
Perceba que para criar um método, iniciamos com a palavra reservada public (isso em PHP 5, falaremos a respeito dessa funcionalidade no decorrer do curso, por enquanto, entenda como o parâmetro que define a visibilidade do método), seguido da palavra reservada function e o nome do método.
A grosso modo, podemos dizer que métodos são funções que agem dentro de uma classe.
É importante salientar que da mesma forma que criamos $p1, poderíamos criar $p2, $p3 e etc, todos com características (atributos) diferentes, mas executando o mesmo método MostrarPessoa().
Vamos utilizar de um exemplo clássico para diferenciarmos classe de objetos:
Uma classe é como uma receita de bolo. Não comemos a receita de bolo, não é verdade? A utilizamos como referência para prepará-lo. A função da classe é semelhante a receita do bolo: Criamos um objeto bolo a partir das especificações da receita.
Voltando aos métodos, vamos agora modelar uma classe um pouco mais completa, ela se chamará conta, e terá os métodos Sacar, Depositar e ObterSaldo.
É importante notar que o método Depositar e o método Sacar recebem valores e esses são atribuidos as variáveis do objeto.
O método ObterSaldo não recebe nenhum valor, ele apensa retorna (return) o valor atual da variável $saldo.
Executando o código:
É mostrado o valor 5400, retornado pelo método ObterSaldo.
Método Construtor
O Construtor é um método (assim como o método Depositar, Sacar e ObterSaldo) executado toda vez que um objeto é instanciado a partir de uma classe. Geralmente é utilizado para executar procedimentos de inicialização de atributos do objeto. Quando é executado o comando $x = New... é automaticamente chamado o método construtor daquela classe.
Perceba que na classe Conta que criamos anteriormente, não criamos o tal método construtor, neste caso, as propriedades do objeto são inicializadas com o valor NULL, daí a necessidade de atribuir valores a todas as propriedades (Cliente, Agencia, Conta e Saldo).
Método Destrutor
Também é um método especial e é executado sempre que atribuímos o valor NULL a um objeto ou quando utilizamos a função unset() e em última instância, quando o programa é finalizado. Este método é comumente usado para apagar arquivos temporários, finalizar conexões e etc.
A seguir vamos criar o método construtor e destrutor para a classe Conta que criamos anteriormente:
Perceba que um construtor é definido pelo método: __construct() (usa-se dois underscores __) e no caso da classe conta, ele foi responsável por definir todos os atributos do objeto.
Vamos agora criar o objeto:
Criamos o objeto conta em $conta1, e no momento de sua criação enviamos os parâmetros que o construtor precisa para preencher os respectivos atributos.
Na imagem abaixo é possível identificar a relação do construtor com o memento de criação do objeto:
Na próxima aula apresentaremos a herança e o conceito de polimorfismo.
Utilize o espaço de comentários para tirar suas dúvidas.
Até a próxima.
Esta é a segunda parte do curso de PHP Orientado a Objetos.
Clique aqui para conhecer a primeira parte.
Ao final deste artigo, você será capaz de:
- Criar métodos para suas classes
- Entender melhor a criação dos objetos
- Entender o método construtor e destrutor
Vamos agora criar uma classe chamada Pessoa:
Class Pessoa{
public $nome;
public $altura;
public $nascimento;
public $salario;
}
Agora vamos criar uma instância de pessoa:
$p1 = new Pessoa();
Agora vamos preencher seus atributos:
$p1->nome = "José da Silva"; $p1->altura = 1.82; $p1->nascimento = "1989-01-22" $p1->salario = 3600;
Podemos verificar os valores inseridos da seguinte forma:
echo " Meu nome é: ".$p1->nome.", minha altura é ".$p1->altura.", nasci no dia ".$p1->nascimento." e hoje meu salário é de ".$p1->salario.".";
Agora vamos criar um método para a classe Pessoa, que trabalhará com as propriedades do objeto. O método terá o nome MostrarPessoa() e basicamente servirá para mostrar os dados do objeto.
Lembre-se que método age dentro do escopo da classe.
Classe alterada:
Class Pessoa{
public $nome;
public $altura;
public $nascimento;
public $salario;
public function MostrarPessoa(){
echo "Nome: ".$this->nome;
echo "Altura: ".$this->altura;
echo "Nascimento: ".$this->nascimento;
echo "Salario: ".$this->salario;
}
}
Temos um novo conceito apresentado aqui. Trata-se da pseudo-variável $this, que serve basicamente para diferenciar as propriedades do objeto de variáveis locais. Lembre-se, $this referencia o objeto ATUAL e acessa suas propriedades.
Agora vamos novamente reescrever o objeto Pessoa executando o método MostrarPessoa():
$p1 = new Pessoa(); $p1->nome = "José da Silva"; $p1->altura = 1.82; $p1->nascimento = "1989-01-22"; $p1->salario = 3600; //executando o método $p1->MostrarPessoa();
Quando o método for executado, todos os dados do objeto P1 serão mostrados na tela.
Perceba que para criar um método, iniciamos com a palavra reservada public (isso em PHP 5, falaremos a respeito dessa funcionalidade no decorrer do curso, por enquanto, entenda como o parâmetro que define a visibilidade do método), seguido da palavra reservada function e o nome do método.
A grosso modo, podemos dizer que métodos são funções que agem dentro de uma classe.
É importante salientar que da mesma forma que criamos $p1, poderíamos criar $p2, $p3 e etc, todos com características (atributos) diferentes, mas executando o mesmo método MostrarPessoa().
Vamos utilizar de um exemplo clássico para diferenciarmos classe de objetos:
Uma classe é como uma receita de bolo. Não comemos a receita de bolo, não é verdade? A utilizamos como referência para prepará-lo. A função da classe é semelhante a receita do bolo: Criamos um objeto bolo a partir das especificações da receita.
Voltando aos métodos, vamos agora modelar uma classe um pouco mais completa, ela se chamará conta, e terá os métodos Sacar, Depositar e ObterSaldo.
class Conta{
public $Cliente;
public $Agencia;
public $Conta;
public $Saldo;
public $Status;
/* Método Sacar()
* Diminui o saldo em quantia
*/
function Sacar($quantia){
if( $quantia > 0 ){
$this->Saldo -= $quantia;
}
}
/* Método Depositar()
* Deposita uma quantia, acrescendo o saldo
*/
function Depositar($quantia){
if ( $quantia > 0 ){
$this->Saldo += $quantia;
}
}
/* Método ObterSaldo()
* Retorna o saldo da conta
*/
function ObterSaldo(){
return $this->Saldo;
}
}
É importante notar que o método Depositar e o método Sacar recebem valores e esses são atribuidos as variáveis do objeto.
O método ObterSaldo não recebe nenhum valor, ele apensa retorna (return) o valor atual da variável $saldo.
Executando o código:
//criando o objeto conta $conta1 = new Conta(); //setando seus atributos $conta1->Cliente = "Jose da Silva"; $conta1->Agencia = 0196; $conta1->Conta = "07126934-24"; $conta1->Saldo = 5000; //executando os métodos $conta1->Depositar(500); $conta1->sacar(100); echo $conta1->ObterSaldo();
É mostrado o valor 5400, retornado pelo método ObterSaldo.
Método Construtor
O Construtor é um método (assim como o método Depositar, Sacar e ObterSaldo) executado toda vez que um objeto é instanciado a partir de uma classe. Geralmente é utilizado para executar procedimentos de inicialização de atributos do objeto. Quando é executado o comando $x = New... é automaticamente chamado o método construtor daquela classe.
Perceba que na classe Conta que criamos anteriormente, não criamos o tal método construtor, neste caso, as propriedades do objeto são inicializadas com o valor NULL, daí a necessidade de atribuir valores a todas as propriedades (Cliente, Agencia, Conta e Saldo).
Método Destrutor
Também é um método especial e é executado sempre que atribuímos o valor NULL a um objeto ou quando utilizamos a função unset() e em última instância, quando o programa é finalizado. Este método é comumente usado para apagar arquivos temporários, finalizar conexões e etc.
A seguir vamos criar o método construtor e destrutor para a classe Conta que criamos anteriormente:
class Conta{
public $Cliente;
public $Agencia;
public $Conta;
public $Saldo;
public $Status;
/* Método Construtor
* Inicializa as propriedades
*/
function __construct($Titular,$Agencia,$Conta,$Saldo,$Status){
$this->Cliente = $Titular;
$this->Agencia = $Agencia;
$this->Conta = $Conta;
$this->Saldo = $Saldo;
$this->Cancelada = $Status;
}
/* Método Destrutor
* Finaliza os objetos
*/
function __destruct(){
echo "O Objeto foi destruído.
";
}
/* Método Sacar()
* Diminui o saldo em quantia
*/
function Sacar($quantia){
if( $quantia > 0 ){
$this->Saldo -= $quantia;
}
}
/* Método Despositar()
* Deposita uma quantia, acrescendo o saldo
*/
function Depositar($quantia){
if( $quantia > 0 ){
$this->Saldo += $quantia;
}
}
/* Método ObterSaldo()
* Retorna o saldo da conta
*/
function ObterSaldo(){
return $this->Saldo;
}
}
Perceba que um construtor é definido pelo método: __construct() (usa-se dois underscores __) e no caso da classe conta, ele foi responsável por definir todos os atributos do objeto.
Vamos agora criar o objeto:
$conta1 = new conta("Jose da silva", "0144", "07126934-24", 5000, "ativa");
echo $conta1->ObterSaldo();
Criamos o objeto conta em $conta1, e no momento de sua criação enviamos os parâmetros que o construtor precisa para preencher os respectivos atributos.
Na imagem abaixo é possível identificar a relação do construtor com o memento de criação do objeto:
![]() |
| Construtor recebendo os parâmetros |
Na próxima aula apresentaremos a herança e o conceito de polimorfismo.
Utilize o espaço de comentários para tirar suas dúvidas.
Até a próxima.
Marcadores:
Classes,
Construtor,
Curso de PHP Orientado a Objetos,
Destrutor,
Métodos,
OO,
Orientação a Objetos,
Orientado a Objetos,
PHP OO,
PHP Orientado a Objetos,
POO,
Programação Orientada a Objetos
sexta-feira, 16 de março de 2012
Curso de PHP Orientado a Objetos - Parte 1
Motivado pela falta de material de qualidade, resolvi iniciar hoje uma série de artigos sobre PHP Orientado a Objetos.
Orientação a Objetos - Estudo das Classes e Objetos
O conceito de classe nada mais é do que uma estrutura que define um tipos de dados, podendo conter variáveis (chamaremos de atributos) e também funções (chamaremos de métodos). Classes manipulam definições e objetos manipulam valores.
Como exemplo, vamos criar uma classe denominada carro. Automaticamente somos levados a pensar em algumas características inerentes aos carros que conhecemos, chamaremos de propriedades:
Propriedades do carro: Ano, modelo, cor, fabricante e etc..
Agora vamos pensar no que o carro faz, chamaremos de métodos:
Métodos: Locomover, frear, buzinar e etc..
Seguindo esta linha de pensamento, vamos criar a classe que define o carro, com suas devidas propriedades e métodos, e em seguida comentaremos.
Para testar, crie um novo arquivo php, salve como Carro.class.php. Não esqueça das tags de abertura e fechamento do php (<?php e ?>).
Este é o escopo básico de uma classe. Na linha 1 temos o que define uma classe (palavra reservada Class), seguida do nome da classe, neste caso Carro.
Observação: Por convenção, o nome das classes devem iniciar com letra maiúscula.
Nas linhas de 3 a 6, temos os atributos da classe, precedidos pela palavra reservada public, usado para indicar que aquele atributo é publico (veremos isso nas próximas aulas).
Um objeto contém exatamente a mesma estrutura e as propriedades de uma classe, no entanto sua estrutura é dinâmica, seus atributos podem mudar de valor durante a execução do programa e podemos declarar diversos objetos oriundos de uma mesma classe.
Exemplo de Objetos
O que fizemos foi criar o objeto carro, e em seguida preenchemos seus atributos.
É importante analizar e entender a metodologia utilizada, fique atento aos comentários.
Continuaremos na próxima aula.
Pré-Requisitos:
- PHP Intermediário
- Básico de MySql
- Básico em UML
Ao final deste artigo, você será capaz de:
- Diferenciar POO da programação procedural
- Entender os benefícios da POO
- Definir Classe e Objetos
- Criar uma classe básica
A velha programação estruturada:
Quando se trata de programação estruturada, estamos lidando com um conceito que dominou o contexto da engenharia de software durante várias décadas.
Na programação estruturada, o blocos de código (chamaremos de procedimentos e funções) se comunicam basicamente por meio de três mecanismos básicos: Sequência, Decisão e Iteração.
Sequência: Representa os passos para executar um programa: Leia um valor, repita esse valor 10 vezes, escreva na tela: "Concluído".
Decisão: Permite o uso de expressões lógicas: SE o valor for igual a x ENTÃO execute a função Y.
Iteração: Permite a execução repetitiva de um determinado bloco de comandos.
Benefícios da programação orientada a objetos:
Reutilização de código: Com certeza uma das maiores vantagens da POO. Uma vez que você escreveu um determinado código, nunca mais será reescrito, no máximo modificado através de algumas técnicas que veremos no decorrer do curso. Característica também denominada DRY (Don't Repeat Yourself).
Eficiência: A POO é associada a melhor eficiência devido suas características inerentes.
Refactoring: Facilidade na hora de modificar a estrutura interna de um código, sem alterar o resultado final.
Manutenibilidade: Facilidade na manutenção do sistema, mesmo quando escrito por terceiros.
Pablo Dall'Oglio define o paradigma da Orientação a Objetos em seu livro, PHP Programando com Orientação a Objetos como:
"A orientação a objetos é um paradigma que representa toda uma filosofia para construção de sistemas. Em vez de construir um sistema formado por um conjunto de procedimentos e variáveis nem sempre agrupadas de acordo com o contexto, como se fazia em linguagens estruturadas (Cobol, Clipper, Pascal), na orientação a objetos utilizamos uma ótica um pouco mais próxima do mundo real. Lidamos com objetos, estruturas que já conhecemos do nosso dia-a-dia e sobre as quais possuímos maior compreensão."
Orientação a Objetos - Estudo das Classes e Objetos
O conceito de classe nada mais é do que uma estrutura que define um tipos de dados, podendo conter variáveis (chamaremos de atributos) e também funções (chamaremos de métodos). Classes manipulam definições e objetos manipulam valores.
Como exemplo, vamos criar uma classe denominada carro. Automaticamente somos levados a pensar em algumas características inerentes aos carros que conhecemos, chamaremos de propriedades:
Propriedades do carro: Ano, modelo, cor, fabricante e etc..
Agora vamos pensar no que o carro faz, chamaremos de métodos:
Métodos: Locomover, frear, buzinar e etc..
Seguindo esta linha de pensamento, vamos criar a classe que define o carro, com suas devidas propriedades e métodos, e em seguida comentaremos.
Class Carro{
public $ano;
public $modelo;
public $cor;
public $fabricante;
}
Para testar, crie um novo arquivo php, salve como Carro.class.php. Não esqueça das tags de abertura e fechamento do php (<?php e ?>).
Este é o escopo básico de uma classe. Na linha 1 temos o que define uma classe (palavra reservada Class), seguida do nome da classe, neste caso Carro.
Observação: Por convenção, o nome das classes devem iniciar com letra maiúscula.
Nas linhas de 3 a 6, temos os atributos da classe, precedidos pela palavra reservada public, usado para indicar que aquele atributo é publico (veremos isso nas próximas aulas).
Um objeto contém exatamente a mesma estrutura e as propriedades de uma classe, no entanto sua estrutura é dinâmica, seus atributos podem mudar de valor durante a execução do programa e podemos declarar diversos objetos oriundos de uma mesma classe.
Exemplo de Objetos
//incluindo a classe que criamos anteriormente
include("Carro.class.php")
//Instanciando (opa, palavrinha nova) um novo objeto
$carro = new Carro();
//Atribuindo valores aos atributos que criamos
$carro->ano = 2012;
$carro->modelo = "C4 VTR";
$carro->cor = "Preto";
$carro->fabricante = "Citroen";
O que fizemos foi criar o objeto carro, e em seguida preenchemos seus atributos.
É importante analizar e entender a metodologia utilizada, fique atento aos comentários.
Continuaremos na próxima aula.
Marcadores:
Classes,
Construtor,
Curso de PHP Orientado a Objetos,
Destrutor,
Métodos,
OO,
Orientação a Objetos,
Orientado a Objetos,
PHP OO,
PHP Orientado a Objetos,
POO,
Programação Orientada a Objetos
Perfil Único (Também conhecido como perfil mandatório)
Olá !
Hoje vamos falar sobre o perfil mandatório no Windows 2003 Server.
O problema:
Temos um domínio, um servidor 2003 com AD e vários usuários. A questão é que nenhum desses usuários podem alterar configurações ou salvar arquivos localmente. Ou seja, a máquina deve se manter no estado original para sempre :)
A solução:
A solução é o tal Perfil mandatório.
Importante: Você deve possuir um servidor Windows 2003 rodando Active Directory.
1 – Abra o Active Directory Users and Computers. Para carregar a tela como mostra a figura 1.1.
6 - Clique com o botão direito do mouse em My Computer (Meu Computador) e selecione a opção Properties (Propriedades), e em seguida clique na guia Advanced (Avançado). Na área User Profiles (Perfil de Usuário), e em seguida, clique no botão Settings (Configurações).
7 - Selecione o Perfil chamado "MODELO", e em seguida clique no botão Copy To (Copiar Para). Como mostra a figura 1.2.
8 - Na caixa de diálogo Copy To (Copiar para) no campo Copy profile to (Copiar o perfil para), como mostra a figura 1.3, digite o caminho UNC do compartilhamento, como por exemplo:

10 – No servidor abra o Windows Explorer e localize a pasta compartilhada onde você salvou o perfil e altere o arquivo ntuser.dat para ntuser.man.
11 – Abra o Active Directory Users and Computers e clique duas vezes sobre um usuário que você pretende implementar o Mandatory Profile.
12 - Clique na guia Profile (Perfil), e no campo Profile Path (Caminho do Perfil), digite o caminho UNC que você digitou no item 8, e em seguida clique em OK. Como mostra a figura 1.4. Figura4
13 – No computador com o Windows XP Professional efetue logon com a conta que você acabou de definir o Mandatory Profile. O resultado será um perfil personalizado por você, no qual o usuário não conseguirá salvar as alterações feitas no seu Desktop quando ele efetuar logoff.
Observaçôes: Esse tópico foi desenvolvido baseado em um cliente Windows XP Professional, e um servidor Windows Server 2003.
Hoje vamos falar sobre o perfil mandatório no Windows 2003 Server.
O problema:
Temos um domínio, um servidor 2003 com AD e vários usuários. A questão é que nenhum desses usuários podem alterar configurações ou salvar arquivos localmente. Ou seja, a máquina deve se manter no estado original para sempre :)
A solução:
A solução é o tal Perfil mandatório.
Importante: Você deve possuir um servidor Windows 2003 rodando Active Directory.
Para criar um Mandatory Profile (Perfil Único ou obrigatório), siga os passos abaixo:
Figura 1.1
2 - Crie um usuário chamado " MODELO". Esse usuário será necessário para que você possa criar um perfil pré-configurado.
3 - Efetue logon com o usuário "MODELO" em um computador com o Windows XP Professional, e faça as configurações necessárias as quais serão aplicadas para os usuários que receberão o perfil obrigatório, como por exemplo, defina um papel de parede padrão para a sua empresa, configure as impressoras, e em seguida efetue logoff.
4 – No servidor com Windows Server 2003, abra o Windows Explorer e crie uma pasta compartilhada e defina as permissões de Full Control (Controle Total) em nível de Compartilhamento para o grupo Everyone (Todos) e Modify (Modificar) em nível de permissão NTFS para o grupo Everyone (Todos). No meu exemplo, eu criei uma pasta chamada "Perfis". Após criar e compartilhar a pasta, feche o Windows Explorer.
5 – No computador com o Windows XP Professional, efetue logon com o usuário Administrator (Administrador) local.
Figura 1.2
ServidorCompartilhamentoNomedoPerfil
* Servidor é o nome da máquina onde você criou o compartilhamento.
* Compartilhamento é o nome do compartilhamento que você criou no item 4.
* NomedoPerfil é nome do perfil modelo criado anteriormente.
* NomedoPerfil é nome do perfil modelo criado anteriormente.
Figura 1.3
9 - No item Permitted to use (Uso Permitido) clique no botão Change (Alterar), e defina que o grupo Everyone (Todos) terá acesso para alterar o perfil, e em seguida, clique no botão OK da caixa de diálogo Copy To (Copiar Para). Feche todas as caixas de diálogo.
11 – Abra o Active Directory Users and Computers e clique duas vezes sobre um usuário que você pretende implementar o Mandatory Profile.
12 - Clique na guia Profile (Perfil), e no campo Profile Path (Caminho do Perfil), digite o caminho UNC que você digitou no item 8, e em seguida clique em OK. Como mostra a figura 1.4. Figura4
Figura 1.4
Observaçôes: Esse tópico foi desenvolvido baseado em um cliente Windows XP Professional, e um servidor Windows Server 2003.
Assinar:
Comentários (Atom)







