Ir para conteúdo

POWERED BY:

Arquivado

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

Tiago Souza Ribeiro

Não entendi direito abstract, static...

Recommended Posts

Olá. Pesquisei um pouco aqui sobre classes e métodos abstratos ou estáticos, mas não entendi muita coisa.

Abstact seria usado quando não se sabe ao certo o tipo de dado que será retornado? Isso é só pra organização, ou muda algo no funcionamento do código?

E statics? Vejo gente usando static em tudo por ser mais fácil de chamar, outros fazem as mesmas classes, métodos, e etc. sem usar isso, pra que serve? Pelo nome dá a impressão de ser algo que não muda, algo que vai retornar sempre o mesmo valor... E assim como o abstract, é apenas para organização ou muda o funcionamento?

 

Aguardo por algum esclarecimento, até mais ^^

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá. Pesquisei um pouco aqui sobre classes e métodos abstratos ou estáticos, mas não entendi muita coisa.

Abstact seria usado quando não se sabe ao certo o tipo de dado que será retornado? Isso é só pra organização, ou muda algo no funcionamento do código?

E statics? Vejo gente usando static em tudo por ser mais fácil de chamar, outros fazem as mesmas classes, métodos, e etc. sem usar isso, pra que serve? Pelo nome dá a impressão de ser algo que não muda, algo que vai retornar sempre o mesmo valor... E assim como o abstract, é apenas para organização ou muda o funcionamento?

 

Aguardo por algum esclarecimento, até mais ^^

 

Abstrato não pode ser instanciado/usado. Não é real, não é concreto.

 

Classes abstratas precisam ser estendidas e métodos abstratos precisam ser sobrescritos.

 

A ideia de classe abstrata é quando você quer/pretende definir uma interface, mas também já quer preparar alguma implementação.

 

Se não houver nenhuma implementação em uma classe abstrata, o que você tem é uma interface.

 

Static é relacionado à classe em si e não às instâncias dela. Métodos e propriedades estáticos também são conhecidos como métodos/propriedades de classe enquanto Métodos e propriedades não estáticos são comumente chamados de métodos/propriedades de instância ou método/propriedade de objeto.

 

O uso de static é encorajado quando certo funcionamento será compartilhado pelas instâncias da classe ou quando a implementação se refere à classe, sem depender de instâncias.

 

Vamos supor que eu queira que, dado um determinado momento, todas as novas instâncias da classe MyCustomString sejam convertidas para CAIXA ALTA:

 

<?php

class MyCustomString
{
   private static $uppercase = FALSE;

   private $value;

   public static function convertNew($switch)
   {
       self::$uppercase = !!$switch;
   }

   public function __construct($value)
   {
       self::$uppercase and $value = strtoupper($value);
       $this->value = (string)$value;
   }

   public function __toString()
   {
       return $this->value;
   }
}

$notupper   = new MyCustomString('my string here.');

MyCustomString::convertNew(1);

$upper      = new MyCustomString('my uppercase string here.');

print $notupper . PHP_EOL;

print $upper . PHP_EOL;

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não sou o cara do PHP, minha praia é desktop, mas essas keywords estão em praticamente todas as funções e todas as linguas existentes:

 

Abstract: Uma classe ou um método que não pode ser chamado nem executado, ele só pode ser herdado por outro método ou classe, ou seja, estendido, logo ele não pode ser considerado o ponto chave de nenhum sistema devido ao fato de ele não ser uma classe executável e sim apenas um conjunto de funções para que outras classes funcionem.

 

Ex:

 

Classe pessoa é abstrata, ela contem todos os campos e todas as variáveis de digitação que fazem a interação com o usuário. Já a classe Usuário é uma classe publica que estende a classe pessoa, sendo assim ela pode se utilizar de todos estes métodos e variáveis e armazenar valores nelas mesmas para futuro uso.

 

Eu costumo usá-las para evitar erros em funções principais, eu "terceirizo" as funções em outras instancias.

 

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

 

Static: Ao pé da letra significa estático, aquilo que não muda de lugar, ou seja, estará sempre lá para qualquer fim. O mesmo ocorre com classes estáticas, variáveis, métodos e etc, isso significa que o nível de proteção que eles possuem é o mais aberto possível, assim sendo eles podem ser acessados por todo e qualquer método dentro da classe ou do sistema.

 

Ex: A classe pessoa possui uma variável do tipo integer que é uma constante valendo 1 e tambem possui outra variável do tipo integer porem estática valendo 4. Ao executar qualquer outra classe ou método, é possível alterar o valor da variável estática, estando este método dentro ou fora da classe pessoa. Portanto ao criar uma classe completamente diferente chamada GUI eu poderei acessar essa mesma variável estática, porem não terei controle algum sobre a outra variável.

 

Espero ter ajudado :)

Compartilhar este post


Link para o post
Compartilhar em outros sites
Se não houver nenhuma implementação em uma classe abstrata, o que você tem é uma interface.

Hmmmmm.... Eu acho que aqui depende.

 

Caso você tenha uma Interface que deverá ser implementada por muitas outras classes, convém criar uma classe abstrata vazia que a implemente e, então, estender todas essas classes dessa uma.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ah, obrigado a todos por responderem. Então, deixa eu confirmar se entendi:

abstract é a mesma coisa que uma interface, só que pode ter mais coisas dentro. Ela não pode ser usada diretamente, apenas por meio de suas extensões.

static está além de objetos e métodos públicos, já que além de pública, ela pode ser modificada externamente.

 

É isso? Sobre o static ainda tenho uma dúvida: se for mesmo isso que eu falei aí encima, porque tem gente que usa private static? Ela vai poder ser modificada normalmente, ignorando o private, ou o quê? Entendi errado?

 

Ah, falando em interface, essa é uma pergunta que esqueci de fazer ao criar o tópico: qual a utilidade das interface's? Sei que servem para "obrigar" as classes que a implementam a ter os métodos pré-estabelecidos, mas qual a vantagem disso? Por que alguém usaria isso? A única situação onde imagino ter uma utilidade (muito pequena) para as mesmas, é em um projeto com vários desenvolvedores envolvidos, onde poderia estabelecer-se padrões para melhor organização de class'es. Teria alguma utilidade usar interface em um projeto privado/pessoal onde apenas um desenvolvedor esteja envolvido? Ele iria se auto obrigar a seguir padrões criados por ele mesmo?

Suponhamos que a seguinte situação seja repetida em um projeto com vários desenvolvedores, e outro com apenas um:

Tenho uma classe pronta com os métodos x, y e z.

Que diferença teria se eu criasse uma interface com esses métodos x, y e z, e modificasse a classe para implementar a interface?

 

Obrigado pela atenção, e até mais laugh.gif

Compartilhar este post


Link para o post
Compartilhar em outros sites

Hmmmmm.... Eu acho que aqui depende.

 

Caso você tenha uma Interface que deverá ser implementada por muitas outras classes, convém criar uma classe abstrata vazia que a implemente e, então, estender todas essas classes dessa uma.

 

Porque??? A vantagem de uma interface sobre uma classe abstrata sem implementações é que eu posso implementar N interfaces, mas só posso estender de uma classe. Eu perco flexibilidade nesse caso!

 

 

Ah, obrigado a todos por responderem. Então, deixa eu confirmar se entendi:

abstract é a mesma coisa que uma interface, só que pode ter mais coisas dentro.

A grosso modo. É quase isso

 

Ela não pode ser usada diretamente, apenas por meio de suas extensões.

 

Não pode ser instanciada. Se eu implemento um método numa classe abstrata e não sobrescrevo-o, eu não estou usando diretamente???

<?php

abstract class EchoOi
{
   public static function doEcho()
   {
       echo 'oi';
   }
}

EchoOi::doEcho();

 

static está além de objetos e métodos públicos, já que além de pública, ela pode ser modificada externamente.

 

Errado e errado. O exemplo do meu primeiro post usa uma propriedade privada e um método público. Todas as regras de instância se aplicam aos estáticos. Inclusive interfaces!

 

<?php

interface Echoes
{
   static function doEcho();
}

abstract class EchoOi implements Echoes
{
   public static function doEcho()
   {
       echo 'oi';
   }
}

EchoOi::doEcho();

 

Ah, falando em interface, essa é uma pergunta que esqueci de fazer ao criar o tópico: qual a utilidade das interface's?

 

Serve para abstrair a implementação. Quando você pede algo que implemente uma certa interface, é como se você fizesse o seguinte pedido:

 

Me dê qualquer coisa que tenha o método "pintarDeBranco" porque eu vou precisar dele

 

Eu posso te passar qualquer instância de qualquer classe com qualquer implementação que, sei que essa "coisa" que eu receber, vai funcionar como eu quero.

 

Teria alguma utilidade usar interface em um projeto privado/pessoal onde apenas um desenvolvedor esteja envolvido? Ele iria se auto obrigar a seguir padrões criados por ele mesmo?

 

Pense em reusabilidade de código. Você não sabe o dia de amanhã. Hoje você sabe ler configurações em XML. Amanhã aprende a usar YAML e quer modificar o seu projeto, que só você usa e só você conhece. Se a sua classe que lê o arquivo de configurações pedir uma instância de XML, você vai ter que reescrevê-la para que ela receba uma instância de XML ou de YAML.

Aí depois você conhece JSON e por aí vai...

Compartilhar este post


Link para o post
Compartilhar em outros sites

 

Não pode ser instanciada. Se eu implemento um método numa classe abstrata e não sobrescrevo-o, eu não estou usando diretamente???

<?php

abstract class EchoOi
{
   public static function doEcho()
   {
       echo 'oi';
   }
}

EchoOi::doEcho();

E se o método não for estático, como faria para usá-lo?

 

Ah, ainda não entendi muito bem a diferença de estático pro normal, além da forma de uso upset.gif

Compartilhar este post


Link para o post
Compartilhar em outros sites

Um exemplo bem simples de se enxergar o que é a keyword static:

<?php
class MyClass {
private static $_instances = 0;
public function __construct() {
	echo 'Objeto Criado' . PHP_EOL;
   	self::$_instances++;
}

public function __destruct() {
	echo 'Objeto Destruído' . PHP_EOL;
   	self::$_instances--;
}

public static function getInstancesCount() {
  	return self::$_instances;
}
}

 

Utitlizando:

$x = array();
for($i = 0; $i < 10; $i++) {
$x[$i] = new MyClass();
echo MyClass::getInstancesCount() . ' instâncias' . PHP_EOL;
}
unset($x);
echo MyClass::getInstancesCount() . ' instâncias' . PHP_EOL;

 

Saída:

henrique@henrique-notebook:~$ php test.php
Objeto Criado
1 instâncias
Objeto Criado
2 instâncias
Objeto Criado
3 instâncias
Objeto Criado
4 instâncias
Objeto Criado
5 instâncias
Objeto Criado
6 instâncias
Objeto Criado
7 instâncias
Objeto Criado
8 instâncias
Objeto Criado
9 instâncias
Objeto Criado
10 instâncias
Objeto Destruído
Objeto Destruído
Objeto Destruído
Objeto Destruído
Objeto Destruído
Objeto Destruído
Objeto Destruído
Objeto Destruído
Objeto Destruído
Objeto Destruído
0 instâncias

Compartilhar este post


Link para o post
Compartilhar em outros sites

Porque??? A vantagem de uma interface sobre uma classe abstrata sem implementações é que eu posso implementar N interfaces, mas só posso estender de uma classe. Eu perco flexibilidade nesse caso!

A vantagem é quando se tem muitas classes. Dessa forma evita-se declarar a implementação em todas as classes individualmente.

 

Assim evita-se esquecer um ou outra, ou ter de abrir dezenas de arquivos quando, de repente, a interface precisar ter seu nome modificado ou seu path alterado (o que caracteriza alterar todos os use's de um namespace).

 

Por exemplo: Todos meus validadores estendem uma classe base que implementa a interface de validação.

 

Todos os validadores do protocolo HTTP implementam uma interface que o caracteriza (HTTP).

 

E cada validador, de cada subcomponente ou RFC, referente ao protocolo HTTP (óbvio), estendem uma classe própria que estende essa segunda.

 

As três classes dispensam implementação, pelo menos até o momento, pois servem apenas para que a interface HTTP e, a exemplo, Headers, respectivamente, não precisem se repetir em todas as 62 classes, de cada cabeçalho:

 

interface Validate {

   public function validate( $data );
}

abstract class AbstractValidate extends Object implements Validate {}

abstract class AbstractHTTP extends AbstractValidate implements HTTP {}

abstract class AbstractHeaders extends AbstractHTTP implements Headers {}

class ContentType extends AbstractHeaders {

   public function validate() {
       // ...
   }
}

E a classe ContentType é instância de Object, implementa Validate, HTTP e Headers e não preciso repetir tudo isso em todos os arquivos, um a um.

Compartilhar este post


Link para o post
Compartilhar em outros sites
Ah, então a propriedade static permite que o valor do objeto ou método seja alterado? Se for, que contraditório, kkkkkkk. Se não for isso, ainda não entendi.

Não... Uma propriedade static é ÚNICA para toda a classe. Todos os objetos de MyClass que fizerem uso de $_instances estarão se referindo à mesma variável, ao passo que se eu declarar uma não estática, cada objeto terá a sua própria variável, veja:

 

<?php
class MyClass {
private $foo = 'foo';
private static $bar = 'bar';

public function setBar($content) {
	self::$bar = $content;
}

public function getBar() {
	return self::$bar;
}

public function setFoo($content) {
	$this->foo = $content;
}

public function getFoo() {
	return $this->foo;
}
}

 

Uso:

$obj1 = new MyClass();
$obj2 = new MyClass();

$obj1->setFoo('Hello World');
echo $obj1->getFoo() . PHP_EOL;
echo $obj2->getFoo() . PHP_EOL;

echo PHP_EOL;

$obj2->setFoo('Bazzinga');
echo $obj1->getFoo() . PHP_EOL;
echo $obj2->getFoo() . PHP_EOL;

echo PHP_EOL;

echo $obj1->getBar() . PHP_EOL;
echo $obj2->getBar() . PHP_EOL;
$obj2->setBar('Blabla');
echo $obj1->getBar() . PHP_EOL;
echo $obj2->getBar() . PHP_EOL;

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ah, então a propriedade static permite que o valor do objeto ou método seja alterado? Se for, que contraditório, kkkkkkk. Se não for isso, ainda não entendi.

 

Static é relacionado à classe em si e não às instâncias dela. Métodos e propriedades estáticos também são conhecidos como métodos/propriedades de classe enquanto Métodos e propriedades não estáticos são comumente chamados de métodos/propriedades de instância ou método/propriedade de objeto.

 

Tiago, um estático pertence à classe. Uma vez que a classe foi definida, o estático já está lá para ser usado, está pronto.

 

Um não-estático depende e pertence a uma instância! Cada vez que faço um new Classe() são requisitados novos espaços na memória para cada uma das propriedades de instância de Classe.

 

<?php

class StaticToBeOrNotToBe
{
   public static function staticMethod()
   {
       return "Olá, eu sou um método estático";
   }

   public function instanceMethod()
   {
       return "Eu sou um método de instância e vou causar um erro!";
   }
}

print StaticToBeOrNotToBe::staticMethod() . PHP_EOL;

print StaticToBeOrNotToBe::instanceMethod() . PHP_EOL;

 

Strict standards: Non-static method StaticToBeOrNotToBe::instanceMethod() should not be called statically

 

Assim evita-se esquecer um ou outra, ou ter de abrir dezenas de arquivos quando, de repente, a interface precisar ter seu nome modificado ou seu path alterado (o que caracteriza alterar todos os use's de um namespace).

 

Por isso temos diversas ferramentas de refatoração. Mas isso não vem ao caso...

 

interface Validate {

   public function validate( $data );
}

abstract class AbstractValidate extends Object implements Validate {}

abstract class AbstractHTTP extends AbstractValidate implements HTTP {}

abstract class AbstractHeaders extends AbstractHTTP implements Headers {}

class ContentType extends AbstractHeaders {

   public function validate() {
       // ...
   }
}

 

Considero isso Açúcar Sintático. Não condeno, pelo contrário. Mas acredito que seja exatamente por causa dessa prática que você acabou com 62 arquivos.

 

Pense comigo, Object possui implementação, correto?

 

Qualquer classe que herde de Object também possui implementação!!

 

Vai me dizer então que AbstractValidate não tem implementação só porque seu corpo é vazio?? E o que foi herdado, foi pro lixo?

 

Abstratos existem apenas com o objetivo de suprir a impossibilidade de embarcar implementação nas interfaces.

 

Se eu tiver

<?php

abstract Clss
{
   public abstract function foo();

   public abstract function bar();
}

 

Eu tenho na verdade uma interface. Mesmo tendo declaração no seu corpo, ela é mais vazia que a sua AbstractValidate que já traz o que Object implementou.

Compartilhar este post


Link para o post
Compartilhar em outros sites

vocês disseram algumas coisas que não sabia e me complicaram um pouco então vamos lá:

 

Static, nós sabemos que quando um método/propriedade ou objeto é declarado como tal você não terá alteração no seu valor certo? ela seria apenas como uma implementação ao seu sistema.

 

algo que fosse assim

 

você tem sua função que conta a + b = c

 

então a statica vem e apenas diz "o resultado é" c..

 

algo parecido com isso?

Compartilhar este post


Link para o post
Compartilhar em outros sites
Por isso temos diversas ferramentas de refatoração. Mas isso não vem ao caso...

Ah, vem sim ao caso. Nem que seja por MP ^_^

 

Considero isso Açúcar Sintático. Não condeno, pelo contrário. Mas acredito que seja exatamente por causa dessa prática que você acabou com 62 arquivos.

Não, não. Tenho 62 arquivos porque cada um valida um item diferente de uma mesma RFC.

 

Se eu coloca-se tudo num arquivo só, além de bagunçado, de difícil manutenção e péssima performance, violaria a SRP do conjunto como um todo.

 

Pense comigo, Object possui implementação, correto?

 

Qualquer classe que herde de Object também possui implementação!!

 

Vai me dizer então que AbstractValidate não tem implementação só porque seu corpo é vazio?? E o que foi herdado, foi pro lixo?

Olhando por esse ângulo, não, claro.

 

Mas 99% das minhas classes estendem Object ou estendem alguma que estende...

Compartilhar este post


Link para o post
Compartilhar em outros sites

vocês disseram algumas coisas que não sabia e me complicaram um pouco então vamos lá:

 

Static, nós sabemos que quando um método/propriedade ou objeto é declarado como tal você não terá alteração no seu valor certo? ela seria apenas como uma implementação ao seu sistema.

 

algo que fosse assim

 

você tem sua função que conta a + b = c

 

então a statica vem e apenas diz "o resultado é" c..

 

algo parecido com isso?

 

Absolutamente... não!

 

Leia e releia o meu primeiro e (agora) penúltimo post.

 

Estático se refere à classe. Independe de instâncias. É isso e apenas isso.

 

Esqueça toda a balela que é imutável, ou que é acessível de qualquer lugar, ou que qualquer um pode acessar e mudar e o escambau. Tá errado! O estático aplica e segue todas as regras que o não-estático segue.

 

Se eu posso limitar a visibilidade de um não estático, eu também posso com o estático.

 

Se eu posso declarar métodos de interface não estáticos, eu também posso declarar métodos de interface estáticos.

 

E por aí vai.

 

Tentando esclarecer pela última vez

 

A única diferença dos métodos/propriedades estáticos é que eles não dependem de uma instância para serem utilizados

 

Fim. Repita e repita e repita essa frase acima até que se torne um mantra e você apenas lembre dela, mesmo que não entenda.

Compartilhar este post


Link para o post
Compartilhar em outros sites

O pessoal confunde muito variável estática com constante.

 

Se fosse imutável, seria constante estática e não variável estática.

 

Fato, também, que todas as contantes são acessadas como se fossem variáveis estáticas do tipo public, pois se mantem no nível da classe, e não no nível de objeto e não podem ser definidas como private ou protected. A única diferença, de constante para variável estática do tipo public, é que a constante, sim, é imutável.

 

Como o Evandro Oliveira mencionou diversas vezes.

A única diferença dos métodos/propriedades estáticos é que eles não dependem de uma instância para serem utilizados

 

Eu postei um exemplo lá no fórum de java sobre o porque de alguns métodos não necessitarem de instância na hora de serem executados. A sintaxe é bem parecida com a do PHP. Quem quiser dar uma lida, acesse aqui.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Única coisa que entendi sobre static: não precisa instanciar. Pronto, é só isso? Quando alguém usaria static ao invés da outra forma "instanciavel"?

 

Só falta isso pra entender :P

 

Declarar membros ou métodos de uma classe como estáticos faz deles acessíveis sem precisar instanciar a classe. Um membro declarado como estático não pode ser acessado com um objeto instanciado da classe (embora métodos estáticos podem).

 

class Minha_class {
   private static $banco;
   // Pra chamá-la, será assim:
   self::$banco;
   // Ao invés de:
   $this->banco;
}

 

Entendeu?

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.