I’ll answer since you have divergent answers and do not know what to do.
You have already learned in the other answers that there is a type compatibility problem. Under normal conditions you cannot print the content of a complex type in general that you have created. no component knows how to print this dataset. You, the type creator need to "teach" the application of how to do this. You are always worried about doing the right thing and this is right. Every class should take responsibility for everything that refers to it.
Then create the method __tostring()
, as defined by the reply of sergiopereira, it is not only useful, it is almost mandatory. In fact some programming languages even require it. Or at least provide a standard method to do this for all classes (the way to do this varies depending on the philosophy of the language).
In fact Guilherme Nascimento is right to call this method magical but has no problem in using it. The builder is also magical. There is and should not even any rule to prevent its use. On the contrary, these are desirable methods in certain situations.
You like to do the right thing. So ask yourself: when do you build an instance of Cachorro
you mean she is associated with a owner or to a owner name? It seems that his initial intention was to use the first form. And I think it’s better. It is not wrong to put only one owner name on the dog if you wish but I think dogs have full owners. How to pass the name you have only the name, does not really associate to the owner. In most situations it is not what you need. I would dismiss any solution upon name.
So your initial solution was correct. The error was in accessing the owner. You tried to print the owner and the application didn’t know how.
If your intention was to explicitly print the owner’s name, then you should ask to print the owner’s name and not to print the owner. It may sound silly but conceptualizing things correctly in programming is fundamental. If you don’t define precisely what you want to do, you won’t be able to express in code correctly.
So the two answers are correct, they just didn’t explain to you when and why to use each one. I would use both.
class Cliente {
private $nome;
public function __construct($nome) {
$this->nome = $nome;
}
public function getNome() {
return $this->nome;
}
public function __toString() {
return $this->nome;
}
}
abstract class Animal {
protected $nome;
protected $dono;
public function __construct($nome, $dono) {
$this->nome = $nome;
$this->dono = $dono;
}
public function getDono() {
return $this->dono;
}
}
class Cachorro extends Animal {
public function __construct($nome, $dono) {
parent::__construct($nome, $dono);
}
}
$ana = new Cliente('ana');
$dog = new Cachorro('Rex', $ana);
echo "Dono: " . $dog->getDono();
echo "\nNome do dono: " . $dog->getDono()->getNome();
Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.
Note that I had the owner and the name of the owner printed out. By chance the result is the same, but take it as a mere fluke. In the future each technique can give different results.
As you want to learn I will take this opportunity to tell you to avoid obvious comments like saying that class is Cliente
is the class Cliente
. You saw how obvious? Comments should say why and not what.
Also try to keep code with consistent organization. It may sound silly but it’s critical to do this. You visualize it better. People who will work with your code, including here better visualize. You start organizing your thoughts in a more organized way.
I’m saying this because it doesn’t seem to be your case but there are novice programmers who are stubborn, who think this is nonsense. And they spend their whole lives doing everything wrong and they never learn to make quality code. I’ve never known in my more than 30 years of experience a good programmer who didn’t care about these details. There are even those who defend the website should serve users anyway, without organization. These people do not understand that they are providing a disservice to users. They are not helping programmers to evolve as needed. Originally the goal of the websites Stackexchange was to make everyone learn, to be different from the forums that only provided solutions. And then the programmers are like the last graph of that page (according to my experience the graphics seem to me quite close to reality in most cases).
I’m not a fan of the term attribute, I prefer field.
our worked as I wished, but now I was in doubt what is the correct and most advisable form, whether yours or @sergiopereira (answer from above) ? not that I’m belittling you
– Leandro Macedo
@Leandromacedo the answer of Spain is just a "magic" method, I disagree with Sergio, because there are better and easier ways for those who use the class, the best is to work with a method
get
(ex:public function getNome() { return $this->nome; }
) (in my opinion). I personally find my answer more correct.– Guilherme Nascimento