Differences in the use of $this, self, Static and Parent

Asked

Viewed 2,720 times

6

I have a question about the "proper" use of $this, self, Static and Parent in some specific scenarios. I know the meaning and theoretical use of each:

  • $this: basically references the object instance. Serves for nonstatic properties and methods. Cannot be used with constant

  • Static: same as $this, but is used for methods, static and constant properties

  • self: used for methods, static properties and constants. In practice in a class hierarchy it references the class in
    who self is being written

  • Parent: reference parent class. Can be used with methods, static properties and constants


In the code below the idea of using Parent was to give the visibility that the so-called method is an "external" or rather inherited method. This would be correct?

<?php

class Pessoa{     

    private $nome;
    private $idade;
    private $sexo;  

    protected function setNome($nome)
    {
        if(is_string($nome)) {
            $this->nome = $nome;
            return true;
        }

        return false;
    }

    protected function setIdade($idade)
    {
        if(is_int($idade)) {
            $this->idade = $idade;
            return true;
        }

        return false;
    }

    protected function setSexo($sexo)
    {
        if($sexo == 'M' || $sexo = "F") {
            $this->sexo = $sexo;
            return true;
        }

        return false;
    }

    public function getNome()
    {
        return $this->nome;
    }

    public function getIdade()
    {
        return $this->idade;
    }

    public function getSexo()
    {
        return $this->sexo;
    }
} 

class Funcionario extends Pessoa
{ 
    private $empresa;
    private $salario;

    public function __construct($nome, $idade, $sexo, $empresa, $salario)
    {
        parent::setNome($nome);
        parent::setIdade($idade);
        parent::setSexo($sexo);
        $this->empresa = $empresa;
        $this->salario = $salario;
    }

    public function getEmpresa()
    {
        return $this->empresa;
    }

    public function getSalario()
    {
        return $this->salario;
    }
}

$funcionario = new Funcionario("Yuri", "19", "Masculino", "Tam", "3000");

echo $funcionario->getNome() . ' Trabalha na: ' . $funcionario->getEmpresa() . ' e ganha ' . $funcionario->getSalario();

Now a macro question: is there any recipe that suggests when it is best to use $this, self, Static or Parent?

2 answers

12

The recipe is: use the one that should be used.

As you well described, the four do different things, so just use the correct, there is no better.

Parent

It refers to the parent class that has been inherited by the current class. Basically it was created so that you do not need, within the child class, to be explicit what is the parent class from which the method will be called, access the attribute, constant, etc.

<?php

class A {
    function example() {
        echo "I am A::example() and provide basic functionality.<br />\n";
    }
}

class B extends A {
    function example() {
        echo "I am B::example() and provide additional functionality.<br />\n";
        parent::example();
    }
}

$b = new B;

// This will call B::example(), which will in turn call A::example().
$b->example();

// Saída:
// I am B::example() and provide additional functionality.
// I am A::example() and provide basic functionality.

Example taken from official documentation. See working on Ideone | Repl.it

In the above code, the method example is rewritten in B, however, its reference in A remains through parent. The only difference to make here, A::example(), does not need to specify the name of the class that has been inherited. If the class name A move to W, simply amend the declaration of B, class B extends W, not in the whole code. The result is exactly the same.

this

Reference to the instance. All that belongs to the instance will be available at $this. Static and constant methods belong to the class itself and are therefore not accessible in this object (in PHP). Adapting a little the previous example, we can do:

<?php

class A {
    function example() {
        echo "I am A::example() and provide basic functionality.<br />\n";
    }
}

class B extends A {
    function example() {
        echo "I am B::example() and provide additional functionality.<br />\n";
    }

    function main() {
        $this->example();
        parent::example();
    }
}

$b = new B;

// This will call B::example(), which will in turn call A::example().
$b->main();

// Saída:
// I am B::example() and provide additional functionality.
// I am A::example() and provide basic functionality.

See working on Ideone | Repl.it

self

The reference in self always points to the own class where it is used and that is the difference to the static. When using self in A, the reference shall be for Class A and when used in B the reference will be B. This influences a lot, for example, when you want to set the return in a method:

<?php

class A {
    public function example() {
        return new self;
    }
}

class B extends A {

}

$b = new B();
$obj = $b->example();

echo get_class($obj), PHP_EOL;

// Saída:
// A

See working on Ideone | Repl.it

Note that when setting the return as self, will be returned an instance object of A, not B.

Static

Similar to self the static shall always refer to the instance used. Sometimes the behavior of static is summed up as a self lazy, because it does not set the reference at the time. Running the same example above, changing self for static, we have:

<?php

class A {
    public function example() {
        return new static;
    }
}

class B extends A {

}

$b = new B();
$obj = $b->example();

echo get_class($obj), PHP_EOL;

// Saída:
// B

See working on Ideone | Repl.it

Even though static is used in class A, the return will be a new instance of B, since the new static was invoked from an instance of B and, as said, static always refers to the current instance class.

In short...

  • parent shall be used when reference is made to the parent class;
  • this shall be used to reference the current instance;
  • self shall be used to reference the class where it is applied;
  • static should be used to reference the class of the instance where it is applied.
  • I believe the biggest doubt is, all the methods have been inherited, I must refer to the inherited methods using $this, that is, work with the methods that have been inherited, or I must access them in the parent class via Parent?

  • 1

    If the method has been inherited, this, because it belongs to the instance. The parent will only be used to invoke a parent class method in case of conflict or static methods.

4


Fabio, I believe that this example you posted should not be followed (that of using Parent::setName). There is no advantage, and if using Parent this way is necessary, it is probably indicative of a design flaw.

If a class inherits the methods, then you should be able to use them the same way you would use the inherited class methods.

Now suppose you need to overwrite the setName method in the daughter class. If you do, Parent::setName will not execute the superscript method, but rather the inherited class method, which would probably not be the expected result.

  • Thanks Thiago, your explanation took away a doubt I had regarding the use of Parent.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.