Yes this parameter passage you are doing is yes a parameter passage by reference and the obtained results respect the paradigms of the POO.
As for your questions:
This would be a standard behavior of object orientation?
Yes this is the behavior is standard for POO. What hurt the understanding, in my view, was the choice of class names and instances.
There is a correct way to send these objects without changing the attributes of the original object?
Yes there is a correct way to send these objects without changing the attributes of the object. What happened in the case was that the language executed exactly what you ordered it to do.
Reinterpretation of the example:
To facilitate understanding I will make some modifications in the examples you gave.
// Mudei o nome da classe Teste para classe Exemplo pois a repetição da
//palavra teste em diferentes contextos estava confusa.
class Exemplo
{
private $atributo;
public function getAtributo(){
return $this->$atributo;
}
public function setAtributo($valor){
$this->$atributo = $valor;
}
// Aqui fiz outra modificação troquei o nome do parâmetro de $teste
//para $alvo. Só para simplificar.
public function incrementar($alvo){
$alvo->atributo += 1;
}
}
The first example I divided into four situations, which I enumerated from 1.1 to 1.4, and instead of an instance of the example class I used two instances.
SITUATION 1.1
I create two instances of Exemplo
, $objeto1
and $objeto2
. I begin the attribute of $objeto1
with 0
and I begin the attribute of $objeto2
with 10
. I used these values to make the results different.
In this example I do $objeto1
increment the attribute of $objeto2
:
$objeto1 = new Exemplo();
$objeto2 = new Exemplo();
$objeto1 ->atributo = 0;
$objeto2 ->atributo = 10;
for($i = 0; $i < 3; $i++){
$objeto1 ->incrementar($objeto2);
}
Results:
$i = 0 => $objeto1 ->atributo = 0 ; $objeto2 ->atributo = 11
$i = 1 => $objeto1 ->atributo = 0 ; $objeto2 ->atributo = 12
$i = 2 => $objeto1 ->atributo = 0 ; $objeto2 ->atributo = 13
SITUATION 1.2
In this example I do $objeto1
increment the own attribute $objeto1
, such as example 1 in question:
$objeto1 = new Exemplo();
$objeto2 = new Exemplo();
$objeto1 ->atributo = 0;
$objeto2 ->atributo = 10;
for($i = 0; $i < 3; $i++){
$objeto1 ->incrementar($objeto1);
}
Results:
$i = 0 => $objeto1 ->atributo = 1 ; $objeto2 ->atributo = 10
$i = 1 => $objeto1 ->atributo = 2 ; $objeto2 ->atributo = 10
$i = 2 => $objeto1 ->atributo = 3 ; $objeto2 ->atributo = 10
SITUATION 1.3
In this example I do $objeto2
increment the attribute of $objeto1
:
$objeto1 = new Exemplo();
$objeto2 = new Exemplo();
$objeto1 ->atributo = 0;
$objeto2 ->atributo = 10;
for($i = 0; $i < 3; $i++){
$objeto2 ->incrementar($objeto1);
}
Results:
$i = 0 => $objeto1 ->atributo = 1 ; $objeto2 ->atributo = 10
$i = 1 => $objeto1 ->atributo = 2 ; $objeto2 ->atributo = 10
$i = 2 => $objeto1 ->atributo = 3 ; $objeto2 ->atributo = 10
SITUATION 1.4
$objeto1 = new Exemplo();
$objeto2 = new Exemplo();
$objeto1 ->atributo = 0;
$objeto2 ->atributo = 10;
for($i = 0; $i < 3; $i++){
$objeto2 ->incrementar($objeto2);
}
Results:
$i = 0 => $objeto1 ->atributo = 0 ; $objeto2 ->atributo = 11
$i = 1 => $objeto1 ->atributo = 0 ; $objeto2 ->atributo = 12
$i = 2 => $objeto1 ->atributo = 0 ; $objeto2 ->atributo = 13
What can be drawn from these examples?
From these examples one can extract that the method is the instrument by which a class allows its instances to perform an action on a parameter.
So if you pass the instance itself as a parameter to be consumed by one of its own methods, the instance becomes the target of its own action. Eg: dog trying to bite its own tail. Situation 1.2 and situation 1.4.
SITUATION 2 and SITUATION 3
For a perfect visualization of POO behavior, I will make a class modification Exemplo
.
class Exemplo
{
private $atributo;
public function getAtributo(){
return $this->$atributo;
}
public function setAtributo($valor){
$this->$atributo = $valor;
}
public function incrementar($alvo){
$alvo->atributo += 1;
}
// Método que engloba o exemplo 2
public function auto_incrementar(){
$this->atributo = 0;
for($i = 0; $i < 3; $i++){
$teste->incrementar($this);
}
}
// Método que engloba ao exemplo 3
public function incrementar_clone(){
$this->atributo = 0;
for($i = 0; $i < 3; $i++){
$teste->incrementar(clone $this);
}
}
}
This time I will create only an object(instance) of the 'Example' class and call the methods auto_incrementar()
and incrementar_clone()
$objeto1 = new Exemplo();
$objeto1 ->atributo = 10;
$objeto1 ->auto_incrementar(); //Note que ates de chamar o método setei o atributo com 10
Upshot:
$i = 0 => $objeto1 ->atributo = 1
$i = 1 => $objeto1 ->atributo = 2
$i = 2 => $objeto1 ->atributo = 3
Why is that?
That’s because the method:
public function auto_incrementar(){
$this->atributo = 0;
for($i = 0; $i < 3; $i++){
$teste->incrementar($this);
}
}
Amounts to:
public function auto_incrementar(){
$this->atributo = 0;
$this->incrementar($this);
}
}
That is to say, it falls into the situation illustrated in 1.2 and 1.4.
The third situation of the example:
$objeto1 = new Exemplo();
$objeto1 ->atributo = 10;
$objeto1 ->incrementar_clone();
Upshot:
$i = 0 => $objeto1 ->atributo = 0
$i = 1 => $objeto1 ->atributo = 0
$i = 2 => $objeto1 ->atributo = 0
Since the method:
public function incrementar_clone(){
$this->atributo = 0; // O atributo passou de 10 para 0
for($i = 0; $i < 3; $i++){
$teste->incrementar(clone $this);
}
}
Amounts to:
public function auto_incrementar(){
$this->atributo = 0
$this->incrementar(clone $this);
}
}
But if we inspect the values of clone $this
. For this we will assume grossly that $objeto2 = clone $this
. Falling under situation 1.1 and 1.3
$i = 0 => $objeto2 ->atributo = 1
$i = 1 => $objeto2 ->atributo = 2
$i = 2 => $objeto2 ->atributo = 3
Would it be any problem if I change the name of the class and instance in the explanation?
– Augusto Vasques
No, it wouldn’t be @Augustovasques
– JrD
Any reason to do this? This class doesn’t make any sense, as it is conceptually wrong, nothing matters. According to your answer I can try to answer the question, including because I have an "opinion" different from the answer already posted. Could put all the code used to test?
– Maniero
The reason would be only for understanding the process, only. The class created only to exemplify the situation, for understanding (apologies to everyone for the names used). I should have created 2 classes to better exemplify the real occurred, I will try to expose the doubt better.
– JrD
@Maniero, The original question did not have the tag
php
. The original tags wereorientação-a-objetos
andengenharia de software
. The editor saw fit to putphp
and removed it from the scope. Pseudo-php was the vehicle the user agreed as suitable to convey his doubt as if it were an algorithm.– Augusto Vasques
@Augustovasques I saw, actually just now I saw that they changed :) My complementary response, for the most part, was not even PHP (just an excerpt I mention this)
– Maniero