Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Extends

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

Welcome back for Episode 3 of our Object Oriented Series! We're ready to get serious about Inheritance. And not just from that rich uncle of yours. I'm talking about extending classes, abstract classes, interfaces, stuff that really makes object oriented code nice but doesn't always look easy at first.

Don't worry this will all start to feel really familiar in a suprisingly small amount of time!

I'm already in the project that we've been working on through this series. If you don't have this yet download the code and use what's in the 'start' directory.

In my terminal I've also started the built in web server with php -S localhost:8000. Be careful to do that in the start directory of the project.

Creating a new RebelShip class

So far in our project we have just this one lonely ship object. We query things from the database and we load this ship. But exciting things are happening and we have a new problem! We want to model two different types of ships. We have normal ships from the empire and since those are kinda evil we also now want rebel ships to set them straight!

In the browser you can see we have two rebel ships in here coming from the database.

I would really like rebel ships to fundamentally work differently. For example, they break down less often and have higher jedi powers. Let me show you what I mean.

Create a new PHP class called RebelShip:

... lines 1 - 2
class RebelShip
{
}

Easy! Since rebel ships aren't exactly like boring old Empire ships let's create a new class or blueprint that models how these work.

Head on into bootstrap.php and require the RebelShip file there:

15 lines bootstrap.php
... lines 1 - 10
require_once __DIR__.'/lib/Model/RebelShip.php';
... lines 12 - 15

We don't have an autoloader yet so we still have to worry about these require statements.

Rebel ships are different than Empire ones but they do share about 99% of their attributes. For example, they both have wings, fire power, defense power, etc.

Class Inheritance with extends

My first instinct should be to go into Ship.php and copy all of the contents and paste that into RebelShip.php since most of it will probably apply. But I shouldn't need to remind you that this would be a silly amount of duplication in our code which would make everyone sad. This is our chance to let classes help us not be sad by using the extends keyword.

By saying class RebelShip extends Ship everything that's in the Ship class is automatically inside of RebelShip:

... lines 1 - 2
class RebelShip extends Ship
{
}

It's as if all the properties and methods of Ship are now a part of the RebelShip blueprint.

In index.php we can say $rebelShip = new RebelShip('My new rebel ship'); and we can just add this to the $ships array:

124 lines index.php
... lines 1 - 6
$ships = $shipLoader->getShips();
$rebelShip = new RebelShip('My new rebel ship');
$ships[] = $rebelShip;
... lines 11 - 124

Remember, down here we iterate over the ships and call things like getName(), getWeaponPower() and getJediFactor() which don't actually live inside of RebelShip:

124 lines index.php
... lines 1 - 72
<?php foreach ($ships as $ship): ?>
<tr>
<td><?php echo $ship->getName(); ?></td>
<td><?php echo $ship->getWeaponPower(); ?></td>
... lines 77 - 85
</tr>
<?php endforeach; ?>
... lines 88 - 124

But when we refresh, it works perfectly!

Lesson number 1: when you have one class that extends another, it inherits (you'll hear that word a lot) all of the stuff inside that parent class. So we can call methods like getName() or getNameAndSpecs() on RebelShip because it inherits that from Ship.

Adding new Methods?

Really, RebelShip works just like a normal class. If you want to, you can add completely new functions. Let's do that with public function getFavoriteJedi() that has an array of some cool Jedis. Then use array_rand to select one of those:

... lines 1 - 2
class RebelShip extends Ship
{
public function getFavoriteJedi()
{
$coolJedis = array('Yoda', 'Ben Kenobi');
$key = array_rand($coolJedis);
return $coolJedis[$key];
}
}

Since this was all done on RebelShip, head over to index.php and call that method. var_dump($rebelShip->getFavoriteJedi() and you can see with my autocomplete it's showing me all of my public functions on both Ship and RebelShip:

126 lines index.php
... lines 1 - 8
$rebelShip = new RebelShip('My new rebel ship');
... lines 10 - 11
var_dump($rebelShip->getFavoriteJedi());die;
... lines 13 - 126

You can even see that the RebelShip methods are displayed bolder and methods from the parent class are lighter.

When we refresh, we see our favorite random Jedi, it works perfectly! Extending classes is great for reusing code without the sad duplication.

Leave a comment!

6
Login or Register to join the conversation
Default user avatar
Default user avatar Aistis Cekanauskis | posted 5 years ago

Guys i have to say, OO Courses 1 and 2 were good, but 3 is just amazing because of the tasks after every single video. I LOVE IT !!! now i watch a video and couple minutes later i can test if i understood correctly :)

3 Reply

Hey Aistis,

Haha, that's amazing! We really glad you like it.

P.S. Not so long ago, we have released the 4th episode of this series: OOP (course 4): Static methods, Namespaces, Exceptions & Traits! Woh!. More cool PHP stuff and even more challenges! Don't forget to check it out!

Cheers!

1 Reply

If PDO is not connecting to mysql you might try to add to the dsn everywhere the port (3306).

For instance:

'db_dsn' => 'mysql:host=localhost:3306;dbname=oo_battle',
That is how I could connect to a docker container with mysql.

Reply
Valgritim Avatar
Valgritim Avatar Valgritim | posted 3 years ago

Hi everyone, Challenge nr 1 doesn't work! even after copying your answer it doesn't work.

Reply
Valgritim Avatar

It's now all good! Don't understand what happened...

Reply

Hey Valerie,

We're sorry about it! Our spam filters have started blocking some good requests lately that leads to some challenge failures. It should work now, and thanks for confirming that it works!

Cheers!

Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

userVoice