If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.
We covered that when you override a function, you override it entirely. In
RebelShip
we're overriding getNameAndSpecs
:
... lines 1 - 2 | |
class RebelShip extends Ship | |
{ | |
... lines 5 - 22 | |
public function getNameAndSpecs($useShortFormat = false) | |
{ | |
if ($useShortFormat) { | |
return sprintf( | |
'%s: %s/%s/%s (Rebel)', | |
$this->getName(), | |
$this->getWeaponPower(), | |
$this->getJediFactor(), | |
$this->getStrength() | |
); | |
} else { | |
return sprintf( | |
'%s: w:%s, j:%s, s:%s (Rebel)', | |
$this->getName(), | |
$this->getWeaponPower(), | |
$this->getJediFactor(), | |
$this->getStrength() | |
); | |
} | |
} | |
} |
which means that when this method is called on a RebelShip
object the getNameAndSpecs
inside of the original Ship
class, i.e. the parent class, is never called. In this case
that's sort of a problem because it leaves us with all this code duplication.
It would be way better if we could somehow call the parent method, getNameAndSpecs
inside of Ship
, and then just add this '(rebel)' part to the end.
We saw in the last chapter, that from within RebelShip
you can call methods that
exist in the parent class as long as they are public
or protected
. Let's try
that here. Add $val = $this->getNameAndSpecs()
. Pass in the $useShortFormat
and then
$val .= ('Rebel');
and finally return $val;
:
... lines 1 - 2 | |
class RebelShip extends Ship | |
{ | |
... lines 5 - 22 | |
public function getNameAndSpecs($useShortFormat = false) | |
{ | |
$val = $this->getNameAndSpecs($useShortFormat); | |
$val .= ' (Jedi)'; | |
return $val; | |
} | |
} |
Doesn't that look a whole lot nicer? Yes, yes it does.
Let's give our experiment here a try. Refresh! Hmmm something is wrong...
(!) Fatal error: Maximum
, let's view the source code since this error is stuck in
our select box. Ah there we go: (!) Fatal error: Maximum function nesting level of '200' reached, aborting!
.
This means that we have a loop in our code, on index line 98 we call getNameAndSpecs
and
then on line 25 of RebelShip
we call getNameAndSpecs
again. This isn't working because
when we call $this->getNameAndSpecs
, it's literally calling this same method again
inside of RebelShip
not the parent function in Ship
.
The way you get this to call the parent function is with a special key word called parent::
:
... lines 1 - 22 | |
public function getNameAndSpecs($useShortFormat = false) | |
{ | |
$val = parent::getNameAndSpecs($useShortFormat); | |
$val .= ' (Jedi)'; | |
return $val; | |
} | |
... lines 30 - 31 |
Let's try this again in our browser, refresh, and checking our dropdown everything is working again. Except, maybe I could use a space here to make things look nicer. There we go.
Don't worry about this parent
keyword too much it's used in exactly one situation calling: a parent
function that you overrode.
We'll see this ::
syntax again later when we talk about static things.
Same. But it’s possible to cheat a bit: just return 2000000 * 2
, and challenge would pass =)
Yeah, not as expected, but correct answer didn't work.
Hey Yaroslavche,
Could you show me the code you're running that's throwing an error? I just tried the correct answer in my browser, and it worked fine
Hi, MolloKhan,
It would sound very strange, but now it works! =)
As I can remember, firstly, I've added to DeathStarII
class next code:
public function getLaserRange()
{
return parent::getLaserRange() * 2;
}
And it contained exactly the same error, as in Serhii's comment: Call to undefined method DeathStar::getLaserRange() in DeathStarII.php on line 7
From error message you can notice, that I've tried call parent method getLaserRange
in DeathStarII
.
Then I've tried as in video example (defined a variable, set from parent call, multiplied by two and return that variable) - same error. Then I've tried just return 2 * 2000000, and it was worked fine, challenge passed (but shouldn't, I suppose. since that's cheating =) ). Then I've checked correct answer, slightly surprised that was the same, that I've tried first time, copy correct answer and got the same error.
IDK why that happened and can't reproduce again =)
Woh, that's weird. My apologies for the inconveniences but at least it's now working :)
Cheers!
I'm running into an error with this exercise. AbstractDeathStar isn't part of this exercise and its not in the visible code, so I don't know where its getting this from.
( ! ) Warning: require(AbstractDeathStar.php): failed to open stream: No such file or directory in index.php on line 3
Call Stack
#TimeMemoryFunctionLocation
10.0051809080{main}( ).../index.php:0
... See the Browser below for the full output.
Hey Terrence,
Are you talking about a challenge in this chapter? What challenge number exactly? Or you can just link to it.
But if the problem with a challenge - please, try to wait about 15 minutes when the challenge is shut down and then reload the page - it will recreate a new challenge instance. This time it should work I think. Sometimes challenges may not work correctly and do not save your code back to the server. Let us know if the issue still relevant to you.
Cheers!
A friendly warning to anyone attempting to run this code inside a virtual machine, I never got the error "maximum function nesting level of '200' reached, aborting!", instead my entire virtual machine was locking up and crashing, and in my windows host it was showing disk usage spiking at 100%.
If anyone else is getting a locked up vm that crashes, this is the issue. I'm not sure if this is a bug in virtual box, ubuntu my guest, windows my host, or what but I do know is running this code completely locks up my ubuntu guest vm!
Hey Galen S.!
Oh no! Sorry about that! And it even affected your Windows host, lame!
There may be one explanation: check if XDebug is installed on your VM. That's a great tool that often can avoid this type of stuff. In fact, I believe it is THE reason that mine hit the error, instead of spinning forever.
Cheers!
Hi, this challenge is not working correctly. It is showing "Fatal error: Uncaught Error: Call to undefined method DeathStar::getLaserRange() in DeathStarII.php on line 7" error.