Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Micilini Roll

teoria das classes estaticas?

Recommended Posts

Pessoal eu estava fazendo um estudo dirigido sobre classes static e cheguei a seguinte conclusão:

 

 

static $quantidade=0;// Cria-se uma variavel chamada quantidade cujo valor inicial é igual a 0, ela tem o atributo chamado static que é:

 

/*

 

Este atributo diz a variavel que ela é uma variavel estatica, ou seja, é o mesmo valor compartilhado por todas as classes,Exemplo pratico:

 

Em um variavel do tipo public chamada nome (public $nome;) nos nao podemos realizar este tipo de comando:

 

new Carrinho('Geladeira111');

new Carrinho('Geladeira'678);

new Carrinho('Geladeira455');

 

pois a variavel so pode assumir uma forma, ja quando a variavel é do tipo static podemos realizar isso, pois é como se ela se duplicasse ou seja acada instancia new passando valores é como se o php criasse outra copia dessa classe com o mesmo nome, ou seja:

 

static $quantidade = "geladeira111";

static $quantidade = "geladeira678";

static $quantidade = "geladeira455";

 

Os valores das classes do tipo estatica so podem ser setados atraves do self:: + variavel, elas nao podem ser setadas atravez do comando $this->quantida = +variavel

 

Estou certo? se estiver errado me corrijam?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não sei se entendi muito bem suas colocações.

 

um método / atributo estático não pode acessar qualquer outro atributo ou método da classe que também não seja estático. A vantagem é que se não se precisa instanciar um objeto para acessar-los.

 

Teoricamente de dentro dos escopo da classe o correto é usar self::$variavel ou self::funcao mas acredito que o $this-> funcione da mesma maneira.

 

De fora da classe você pode acessa-los com o nome da classe mais "::" e o método ou atributo estático. ex.: nomedaclasse::$variavel

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não aprofundando muito, mas:

 

<?php

Class Carrinho
{
  static $quantidade =0;

  public function __construct($qtd){
     // $this->quantidade = $qtd; // Erro -> conteudo estatico não é acessivel pelo $this
     self::$quantidade = $qtd; // Correto
  }

  static public function getQtd(){
     return self::$quantidade;
  }
}

$carrinho = new Carrinho(5);
$carrinho->getQtd(); // Nao acessivel porque p método é estatico
echo Carrinho::getQtd();

Carrinho::$quantidade = 5;

echo Carrinho::getQtd();

Compartilhar este post


Link para o post
Compartilhar em outros sites

Calma rsrs ainda sou iniciante em orientação a objetos vamos la a primeira coisa que digo é que segui esta linhas de raciocinio observe:

 

Public -> Todos as variaveis ou funções que virem com este metodo podem ser acessados tanto de dentro como de fora da classe exemplo:

 

Banheiros quimicos, calçadas, protitutas sao publicas e podem ser ultilizados tanto pelo governo como o povo

Falar, olhar, correr é publico pois todos nos temos estas caracteristicas

 

 

Private -> sao exclusivamente da classe e nao podem ser herdadas, exemplo:

 

Gosto (musical,alimento, etc..) nao se descute assim como as caracteristicas de uma pessoa, ela nao podem ser herdadas pois nen sempre um pai que gosta de rock o filho gostará de rock.O pai que seja super engraçado o filho sera, o pai tem conhecimento de fisica e quando o beber nascer ja sabendo fisica...

 

Protected -> so podem ser acessadas dentro da classe e podem ser herdadas, Exemplo:

 

A cor dos olhos, da pele entre outras caracteristicas geneticas, Fortuna... podem ser herdadas e usada pelos membros da familia, mas outra pessoa que nao seje da familia nao tem acesso a esse tipo de coisa.

 

Static -> não pode acessar qualquer outro atributo ou método da classe que também não seja estático. A vantagem é que se não se precisa instanciar um objeto para acessar-los. Exemplo:

 

OK, ate agora nao consegui usar um exemplo pratico para facil entendimento....

Compartilhar este post


Link para o post
Compartilhar em outros sites

Imagine uma classe que valide coisas, retorna true caso seja válido e falso caso não:

 

 

class Valida{



static public function email(){
}


static public function cpf(){

}


}

 

com a classe estatica basta fazer isso:

 

 

$email = "email@host.com";


$eValido=Valida::email($email);

Se a classe não fosse estática precisaríamos instanciar um objeto Valida, o que consumiria mais recursos e daria um código mais longo e menos legível.

 

exe.:

 

 

$validador=new Valida();

$email = "email@host.com"; 

$eValido=$validador->email($email);

 

Existem outras possibilidades interessantes, como usar métodos estáticos para instanciar outros objetos, com isso podemos deixar programado a variáveis com que eles serão construídos pelo método estático. Depois para instancia-los bastaria um "getInstance()".

 

Métodos estáticos são muito importantes também para o padrão Registry, que funciona como um "quadro negro" quase como uma global onde a informações são registradas e são acessíveis a qualquer parte da aplicação.

Compartilhar este post


Link para o post
Compartilhar em outros sites

aaaah agora com esse exmplos entendi entao vamos lá:

 

Quando definimos uma função ou variavel do tipo public,protected ou private para acessar estas variaveis ou funções é necessario instanciar a classe ou seja:

 

new Valida(); // Inicia a classe que sera executada , funciona como um power on de um computador ou uma ignição de um carro.

 

Ja quando funções ou variaveis sao do tipo static nao é necessario mais iniciar a classe, é simplismente adicionar o nome da classe e fazer uma referencia :: + variavel ou função, exemplo:

 

Valida::email($email);

 

Mas ai tem contradições, pois sera que o comando:

 

Valida::email($email); 

Nao seria a mesma coisa que esse:

 

$validador=new Valida();

$eValido=$validador->email($email);

 

So que de uma forma mais simplificada? Ou seja, para o programador pareçe ser simplificada mas pro PHP é a mesma coisa nao (PHP executa os mesmos procedimentos tanto no simplificado quando no normal)?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Se não há instancia, o interpretador não vai alocar memoria para tal.

 

De acordo com meu exemplo:

 

 

new Valida(); // Inicia a classe que sera executada , funciona como um power on de um computador ou uma ignição de um carro.

 

então voce esta querendo dizer que é a mesma coisa do que eu andar com um carro ou executar um game no pc, mesmo nao tendo liga-o ou feito a ignição?

Compartilhar este post


Link para o post
Compartilhar em outros sites

A questão esta no processo, em um site grande por exemplo você pode precisar validar milhares de emails, se este método não for estático pode ser preciso instanciar esses milhares de objetos em diferentes partes do sistema. cada um deles consumindo memoria e deixando o servidor mais lento. Com método estático você não precisa se preocupar com coisas como o tempo de vida dos hipotéticos objetos Valida e a memoria que eles estão consumindo, existe apenas uma classe lidando com o problema no sistema e não diversos objetos diferentes.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Em orientação a objetos, estáticos têm duas funções: criar objetos e ter estado global (evil evil evil). Em linguagens que não contêm suporte para funções, como Java, eles também são usados para fazer pure functions (funções sem efeitos colaterais e sem estado, apenas com input => output).

 

- Criação de objetos:

 

Vamos supor que nós temos um componente para fazer comparações matemáticas (>, <, >=, etc.).

interface Operator
{
    public function matches($x, $y);
}

class GreaterThan implements Operator
{
    public function matches($x, $y)
    {
        return $x > $y;
    }
}

class LessThan implements Operator
{
    public function matches($x, $y)
    {
        return $x < $y;
    }
}

class Comparison
{
    private $operator;
    private $x;
    private $y;

    public function __construct(Operator $operator, $x, $y)
    {
        $this->operator = $operator;
        $this->x = $x;
        $this->y = $y;
    }

    public function matches()
    {
        return $this->operator->matches($this->x, $this->y);
    }
}

E para utilizar esse componente, perceba que temos um pouco de burocracia:

$comparison1 = new Comparison(new GreaterThan(), 5, 10);
$comparison1->matches(); // false

$comparison2 = new Comparison(new LessThan(), 5, 10);
$comparison2->matches(); // true

Para isso, poderíamos criar métodos estáticos na nossa classe Comparison para facilitar a criação:

public static function greaterThan($x, $y)
{
    return new self(new GreaterThan(), $x, $y);
}

public static function lessThan($x, $y)
{
    return new self(new LessThan(), $x, $y);
}

E o uso fica mais fácil:

$comparison1 = Comparison::greaterThan(5, 10);
$comparison1->matches(); // false

$comparison2 = Comparison::lessThan(5, 10);
$comparison2->matches(); // true

Esse tipo de técnica é conhecida como "Static Factory". Não digo que seja bom ou ruim, depende muito do caso e deve-se tomar cuidado com o Open/Closed Principle.

 

- Estado global:

 

Durante muito tempo isso foi muito aplicado e falado (positivamente) na comunidade PHP, mas atualmente, com o começo da maturidade da linguagem e do ecossistema, hoje isso é evitado. Porém, vamos ver de qualquer forma.

 

Antes de tudo, é necessário compreender o estado em OOP, que é armazenado nas propriedades:

class Rectangle
{
    public $height = 0;
    public $weight = 0;
}

$rectangle1 = new Rectangle();

var_dump($rectangle1->height); // 0
var_dump($rectangle1->weight); // 0

$rectangle1->height = 5.75;
$rectangle1->weight = 9.40;

var_dump($rectangle1->height); // 5.75
var_dump($rectangle1->weight); // 9.40

Os objetos têm estado independente, ou seja, se eu mudar o estado de algum objeto, ele não muda o do outro:

$rectangle1 = new Rectangle();
$rectangle1->height = 5.75;
$rectangle1->weight = 9.40;

$rectangle2 = new Rectangle();
$rectangle2->height = 2.15;
$rectangle2->weight = 2.80;

var_dump($rectangle1->height); // 5.75
var_dump($rectangle1->weight); // 9.40
var_dump($rectangle2->height); // 2.15
var_dump($rectangle2->weight); // 2.80

No caso de estáticos, o estado é da classe e não do objeto, até porque não há um objeto (instância):

class StaticRectangle
{
    public static $height = 0;
    public static $weight = 0;
}

StaticRectangle::$height = 5.75;
StaticRectangle::$weight = 9.40;

StaticRectangle::$height = 2.15;
StaticRectangle::$weight = 2.80;

var_dump(StaticRectangle::$height); // 2.15
var_dump(StaticRectangle::$weight); // 2.80

No caso acima, não temos um objeto e acessamos a classe diretamente. Se eu mudo o estado, eu mudo globalmente e não somente no objeto.

 

Na prática, isso é usado para manter um estado de algo, como um banco de dados, logger, sistema de cache e afins, surgindo dois padrões: Singleton e Registry. Contudo, evite fazer isso, não é uma boa prática.

 

- Pure functions:

 

Elas não são nada mais do que funções que recebem alguns parâmetros e retornam algum valor, sem nenhum efeito colateral, sem acessar estado externo.

 

Na maioria das linguagens, é possível criar funções, mas em algumas não é porque elas obrigam você a trabalhar com classes. Em PHP, costuma-se fazer pure functions com métodos estáticos porque não existe autoloading para funções.

class Inflector
{
    public static function camelCase($string)
    {
        return lcfirst(self::studlyCaps($string));
    }

    public static function studlyCaps($string)
    {
        return str_replace(
            ' ',
            '',
            ucwords(str_replace(['-', '_'], ' ', $string))
        );
    }
}

echo Inflector::camelCase('Alguma frase grande'); // algumaFraseGrande
echo Inflector::studlyCaps('Alguma frase estranha'); // AlgumaFraseEstranha

Mas nada nos impediria de fazer isso de forma orientada a objetos:

class Inflector
{
    private $string;

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

    public function camelCase()
    {
        return lcfirst($this->studlyCaps());
    }

    public function studlyCaps()
    {
        return str_replace(
            ' ',
            '',
            ucwords(str_replace(['-', '_'], ' ', $this->string))
        );
    }
}

echo (new Inflector('Alguma frase grande'))->camelCase(); // algumaFraseGrande
echo (new Inflector('Alguma frase estranha'))->studlyCaps(); // AlgumaFraseEstranha

--------------------------------------------------

 

Teoricamente de dentro dos escopo da classe o correto é usar self::$variavel ou self::funcao mas acredito que o $this-> funcione da mesma maneira.

 

Para acessar métodos e propriedades estáticas, usa-se self:: ou static::, $this-> é apenas para não-estáticos. Se rodar em E_STRICT dará erro.

 

Public -> Todos as variaveis ou funções que virem com este metodo podem ser acessados tanto de dentro como de fora da classe exemplo:

 

Banheiros quimicos, calçadas, protitutas sao publicas e podem ser ultilizados tanto pelo governo como o povo

Falar, olhar, correr é publico pois todos nos temos estas caracteristicas

 

 

Private -> sao exclusivamente da classe e nao podem ser herdadas, exemplo:

 

Gosto (musical,alimento, etc..) nao se descute assim como as caracteristicas de uma pessoa, ela nao podem ser herdadas pois nen sempre um pai que gosta de rock o filho gostará de rock.O pai que seja super engraçado o filho sera, o pai tem conhecimento de fisica e quando o beber nascer ja sabendo fisica...

 

Protected -> so podem ser acessadas dentro da classe e podem ser herdadas, Exemplo:

 

A cor dos olhos, da pele entre outras caracteristicas geneticas, Fortuna... podem ser herdadas e usada pelos membros da familia, mas outra pessoa que nao seje da familia nao tem acesso a esse tipo de coisa.

 

Static -> não pode acessar qualquer outro atributo ou método da classe que também não seja estático. A vantagem é que se não se precisa instanciar um objeto para acessar-los. Exemplo:

 

Public, protected e private são tipos de visibilidade. Estáticos e não-estáticos tem a ver com escopo. Não misture ambas e não tente pensar no mundo real para entender orientação a objetos.

 

Se a classe não fosse estática precisaríamos instanciar um objeto Valida, o que consumiria mais recursos e daria um código mais longo e menos legível.

 

A OO é verbosa por natureza. No caso de validação, não criaríamos um método para uma validação, pois iria violar o Open/Closed Principle e o Single Responsibility Principle, que são relevantes para um bom design.

interface Rule
{
    public function isValid();
}

class Email implements Rule
{
    private $email;

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

    public function isValid()
    {
        return filter_var($this->email, FILTER_VALIDATE_EMAIL) !== false;
    }
}

class CPF implements Rule
{
    private $cpf;

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

    public function isValid()
    {
        $c = preg_replace('/\D/', '', $this->cpf);

        if (strlen($c) != 11 || preg_match("/^{$c[0]}{11}$/", $c)) {
            return false;
        }

        for ($s = 10, $n = 0, $i = 0; $s >= 2; $n += $c[$i++] * $s--);

        if ($c[9] != ((($n %= 11) < 2) ? 0 : 11 - $n)) {
            return false;
        }   

        for ($s = 11, $n = 0, $i = 0; $s >= 2; $n += $c[$i++] * $s--);

        if ($c[10] != ((($n %= 11) < 2) ? 0 : 11 - $n)) {
            return false;
        }

        return true;
    }
}

class Validator
{
    private $rules = [];

    public function addRule(Rule $rule)
    {
        $this->rules[] = $rule;
        return $this;
    }

    public function validate()
    {
        foreach ($this->rules as $rule) {
            if (! $rule->isValid()) {
                // Procedimentos quando há uma falha
            } else {
                // Procedimentos quando dá certo
            }
        }
    }
}

$validator = new Validator();
$validator->addRule(new Email($_POST['email']))
          ->addRule(new CPF($_POST['cpf']))
          ->validate();

Espero ter contribuído :).

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Enrico Pereira, muito boa sua contribuição!!!

 

OFF

 

Tenho que tirar o chapeu!!!

536px-Coolidge_after_signing_indian_trea

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.