Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
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 ^^
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 :)
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.
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 /applications/core/interface/imageproxy/imageproxy.php?img=http://forum.imasters.com.br/public/style_emoticons/default/laugh.gif&key=fb9a849ac525d2fd317adad061adf02e38bd5f5cb2c664d803c1667dd70a2af1" alt="laugh.gif" />
>
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...
>
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 /applications/core/interface/imageproxy/imageproxy.php?img=http://forum.imasters.com.br/public/style_emoticons/default/upset.gif&key=a5f2b14a4bbe3156567f0725b59e84a20911d231cc45e3abef7fbe7ccb1c7261" alt="upset.gif" />
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
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.
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.
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;>
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.
Recomendo clique.
Um tutorial PHP orientado a objetos dividido em 12 partes.
>
Recomendo clique.
Um tutorial PHP orientado a objetos dividido em 12 partes.
pra mim o "clique" não funcionou..
tae o link: http://cafeesoftware.com/curso-de-php-orientado-a-objetos-parte-1
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?
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...
>
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.
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.
Ú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
>
Ú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?
Então, quando você define uma propriedade ou método como estático (static), o seu comportamento não é alterado, somente é alterado a forma que você vai chamá-lo.
Errado, o comportamento é alterado sim, pois a propriedade ou método é 'global' para aquela classe. Se você alterar uma propriedade estática, alterará para todos os objetos daquela classe.
Releia o post #11 para entender, Tiago... A 'regra' para se utilizar estático é algo que você deseja que seja único para todos os objetos da classe.
>
Ú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
exemplo prático, de uma implementação real e em pleno funcionamento:
www.php.net/manual/en/pdo.getavailabledrivers.php
Olha o paradoxo:
Eu preciso de um driver válido pra criar uma nova instância.
Como eu faria pra saber quais drivers estão disponíveis se eu tivesse que criar uma instância pra isso?
Ainda sugiro que você releia esse tópico, pois, o mesmo já contém diversos exemplos.
É sempre bom revisitar um escrito que não havíamos entendido anteriormente. Impressionante como um novo ponto de vista pode ser esclarecedor.
Aaaah, acho que entendi um pouco.
No exemplo do getAvailableDrivers o static é usado para que a pessoa não precise instanciar o PDO, criando uma conexão e tudo mais só pra ver os drivers disponíveis. É isso?
E Henrique: com único, você quer dizer algo global dentro da classe, não podendo ter nenhum outro objeto ou método com mesmo nome? Vou reler os posts pra ver se entendo...
Não tem muito a ver com OO, mas eu sempre quis entender o uso de static quando dentro de uma função, junto à uma variável normal.
>
Não tem muito a ver com OO, mas eu sempre quis entender o uso de static quando dentro de uma função, junto à uma variável normal.
serve pra que aquele valor seja declarado apenas uma vez
function contar() {
static i=0;
echo i++ . PHP_EOL;
}
contar();
contar();E isso serve pra quê, exatamente?Sabe,na prática.
>
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
{