27
What’s the difference between static
and self
? Exemplify situations that justify your different uses. What does this have to do with late Static Binding?
27
What’s the difference between static
and self
? Exemplify situations that justify your different uses. What does this have to do with late Static Binding?
27
static
is used to define that a method or attribute in a class is static. This means (as someone who knows OO must know) that that method/attribute belongs to the class and not to an instance of it and can therefore be accessed without instilling a new object.
Example:
<?php
class Foo
{
public static $meu_estatico = 'foo';
public function valorEstatico() {
return self::$meu_estatico;
}
}
It is possible to use something like :
print Foo::$meu_estatico . "\n";
Pure like that, without it being necessary to make a $a = new Foo()
before.
Note in the example that the self
, that was also questioned. It is only used to use a static variable within the class that contains it.
$a = new Foo();
echo $a->valorEstatico() // tem como saída "foo"
It is important to make clear that a static value belongs to the class and not to the instances, but can be used within the class via self
.
This is very interesting for values you want available for the entire application, for example. If they change in the class only once the entire application has access to the same values.
These examples were taken from http://www.php.net/manual/en/language.oop5.static.php
AFTER UPDATE OF THE QUESTION . . .
When a class uses a static method that has been inherited from another, static values within that inherited method will refer to the parent class if the self
. To use the specialized class (daughter) as a reference for these static values, the self Static Binding is used. Understand Binding as "link" (I don’t know if it helps much) . Quoting doc is an example:
This feature was named "late Static bindings" with a pespectiva internal in mind. "Late Binding" comes from the fact that Static:: no longer be solved using the class where it is set but it will be evaluated using runtime information. It was also called "Static Binding" as can be used for (but not limited to) call for static methods. (http://php.net/lsb)
Examples (also of Ocds, but merged the two)
<?php
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
self::who(); // Isso vai sair como "A", o nome da classe mãe
}
public static function test2() {
static::who(); // Já esse aqui vai sair "B", o nome da classe filha
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test(); // Isso vai sair como "A", o nome da classe mãe
B::test2(); // Já esse aqui vai sair "B", o nome da classe filha
?>
11
self
serves to access class properties within itself, that is, for all instances there will only be a single value since the property is class.
static
is a qualifier that generates a class property instead of an object property or class instance, the code below exemplifies the use of the two and also differentiates a property of an object from the class of a class property:
<?php
class X {
private $non_static_member = 1; //propriedade do objeto da classe
private static $static_member = 2; // propriedade da classe
function __construct() {
// Acessando propriedade do objeto da classe
echo $this->non_static_member . ' '
// Acessando propriedade da classe
. self::$static_member;
}
}
// Precisamos instanciar a classe para acessar as propriedades do objeto criado.
(new X())->$non_static_member;
// Acessamos a partir da classe.
X::static_member
?>
Basically late Static Binding is used to reference a specialization (daughter class) from an implementation performed in the generalized class (mother class), allowing polymorphism between daughter classes.
<?php
class DartVader {
public static function say() {
echo "I'm your father";
}
public static function sayToLuky() {
self::say(); // "I'm your father"
}
public static function sayToDartVader() {
static::say(); // Can be "Han Solo my love!" or "Noooooo!"
}
}
class Luke extends DartVader {
public static function say() {
echo "Noooooo!";
}
}
class Leia extends DartVader {
public static function say() {
echo "Han Solo my love!";
}
}
Leia::sayToDartVader() // "Han Solo my love!"
Leia::sayToLuky() // "I'm your father"
Luke::sayToDartVader() // "Noooooo!"
Luke::sayToLuky() // "I'm your father"
?>
4
A keyword self
Accesses a property within the class and is equivalent to: $this
. Ex.:
class Foo {
function __construct() {
return self::bar();
}
public function bar() {
return "bar";
}
}
When executing $foo = new Foo()
is returned the value of the bar function within the class.
A keyword static
makes a function accessible without the need to instantiate the class where it is "hosted". For example:
class Foo {
public static function bar() {
return get_class() . "bar";
}
}
echo Foo::bar();
This code will be printed Foobar
. Recapping self
serves to access functions or variables that are within a class and is equivalent to $this
, already static
serves to access functions or variables without calling a class.
This is how much is inherited by another static attributes class.
0
Given the excellent answers, I want to emphasize the question of inheritance. But first, let’s recap the following:
self
:It is used to return the value of a property or call (run) some static method - MUST be used WITHIN of the class in question with the operator ::
;
static
:Is used for:
Declare a property or method to be static. That is, it is not necessary to instantiate the class in question (new MinhaClasse();
);
Return the value of a static property or call (run) some static method - CAN be used INSIDE AND OUTSIDE of the relevant class with the same operator ::
;
Consider the following code:
class Foo
{
public static $variavel = 'Valor A';
public static function valorVariavel
{
return self::$variavel;
}
}
echo Foo::valorVariavel(); // retorna "Valor A" que pertence a classe "Foo";
I declared the class Foo
with the static method valorVariavel()
that returns the value of static property $variavel
. Then I called the static method with the operator ::
(instead of the operator ->
).
Now that comes the catjump! Consider the following code:
class Bar extends Foo
{
public static $variavel = 'Valor B';
}
echo Bar::valorVariavel(); // retorna "Valor A" que pertence a classe "Foo";
In class Bar
declared the static property $variavel
worthwhile Valor B
, but when calling the method, returns Valor A
.
This happens because the self
returns what’s in your class. Whether property or method.
To circumvent this, we can return the property value with static
, instead of self
:
class Foo
{
public static $variavel = 'Valor A';
public static function valorVariavel()
{
return static::$variavel;
}
}
class Bar extends Foo
{
public static $variavel = 'Valor B';
}
echo Foo::valorVariavel(); // retorna "Valor A" que pertence a classe "Foo";
echo Bar::valorVariavel(); // retorna "Valor B" que pertence a classe "Bar";
With static
, we always return the value of the LAST DECLARATION, following the order of inheritance (see next example).
It is also legal to always declare static properties in child classes when you want to change their value. Or else the value of the parent class (which has been extended) will be overwritten. What would eventually affect all other classes extending this same parent class that are being instantiated/called later in the same script (execution).
Take this example:
class Foo
{
public static $variavel = 'Valor A';
public static function valorVariavel()
{
return static::$variavel;
}
public static function setVariavel($valor)
{
static::$variavel = $valor;
}
}
class Bar extends Foo
{
// propriedade não foi declarada
}
class FooBar extends Foo
{
public static $variavel = 'Valor D';
}
echo Foo::valorVariavel(); // retorna "Valor A" que pertence a classe "Foo";
echo Bar::valorVariavel(); // retorna "Valor A" que pertence a classe "Bar";
Bar::setVariavel('Valor C');
echo Foo::valorVariavel(); // retorna "Valor C" que pertence a classe "Foo";
echo Bar::valorVariavel(); // retorna "Valor C" que pertence a classe "Bar";
echo FooBar::valorVariavel(); // retorna "Valor D" que pertence a classe "FooBar";
FooBar::setVariavel('Valor E');
echo Foo::valorVariavel(); // retorna "Valor C" que pertence a classe "Foo";
echo Bar::valorVariavel(); // retorna "Valor C" que pertence a classe "Bar";
echo FooBar::valorVariavel(); // retorna "Valor E" que pertence a classe "FooBar";
When I first started learning POO, I took a "blessed beating" with these differences of static
for self
. I hope this will clarify the question of inheritance.
Browser other questions tagged php oop
You are not signed in. Login or sign up in order to post.
+1 being +0.5 for correctness and +0.5 for references to Star Wars.
– Oralista de Sistemas