Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Broken Ship

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $6.00

Here's the really beautiful thing about abstract classes. You may create some of these because you have a situation similar to the one we've been working on in this project. Or, you may be using someone else's code like a third party library that you downloaded via the Composer package manager. You might even read in that library's documentation that if you want to create a new ship class you just need to extend AbstractShip.

What's really great is that AbstractShip now tells you exactly what you need to do to create a new ship class with its three abstract functions that you must fill in:

... lines 1 - 2
abstract class AbstractShip
{
... lines 5 - 15
abstract public function getJediFactor();
... lines 17 - 20
abstract public function getType();
... lines 22 - 25
abstract public function isFunctional();
... lines 27 - 121
}

A third group has joined the battle and we have a new type of ship. They're not very good mechanics, so we'll call this a broken ship. This is simple, the ship is always broken.

Create a new php class called BrokenShip. Of course now make it extend AbstractShip:

... lines 1 - 2
class BrokenShip extends AbstractShip
{
}

Let's pretend like we don't know that there are any abstract methods in the parent class. So we won't do anything here except putting in the extends code. Head over to bootstrap.php and require our useless new BrokenShip:

17 lines bootstrap.php
... lines 1 - 12
require_once __DIR__.'/lib/Model/BrokenShip.php';
... lines 14 - 17

Back in index.php for now, let's just add $brokenShip = new BrokenShip(); and add it to our ships array:

126 lines index.php
... lines 1 - 8
$brokenShip = new BrokenShip('Just a hunk of metal');
$ships[] = $brokenShip;
... lines 11 - 126

We can do this because we know that BrokenShip extends AbstractShip. And down here, when we use those ship objects we're just calling methods on the AbstractShip.

Back to the browser, refresh! Yes, what a huge beautiful error. It says:

Class BrokenShip contains 3 abstract methods and must therefore be declared abstract or implement the remaining methods.

And then it goes on and lists the methods.

In other words, it's saying "Hey buddy! You need to add those three methods into this class!" It's always giving you an out to declare the class abstract if you want to, and you might do this if you wanted an abstract class inside an abstract class with some additional public functions. But we've all seen where that goes in the move inception.

In our case we want this to be a concrete class, meaning one that we can instantiate. When we go over to AbstractShip we say "Oh yea, I see there's a getJediFactor function that I need to add." Take off the abstract to turn it into a real function, and since this ship is always broken we don't care about the Jedi factor so let's just return 0:

... lines 1 - 2
class BrokenShip extends AbstractShip
{
public function getJediFactor()
{
return 0;
}
... lines 9 - 18
}

When we refresh after that we get the same error, but we're down to just 2 missing abstract methods, getType and isFunctional.

Head back into AbstractShip and grab those, pop off the abstract word at the beginning after we paste them into BrokenShip. And we'll fill in the details of getType by returning 'Broken'. And we'll fill in isFunctional by returning false:

... lines 1 - 2
class BrokenShip extends AbstractShip
{
... lines 5 - 9
public function getType()
{
return 'Broken';
}
public function isFunctional()
{
return false;
}
}

Without really knowing anything I extended AbstractShip and that class told me exactly what I needed to have in my subclasses.

And when we refresh, we have one more error! We're missing argument 1 to AbstractShip::__construct. That's my bad. In index.php here BrokenShip still has a constructor argument which is the name so let's not forget to fill that in with "I am so broken":

126 lines index.php
... lines 1 - 8
$brokenShip = new BrokenShip('Just a hunk of metal');
... lines 10 - 126

Refresh again, and things look great! We've got our four original ships and our new broken one. Which is always broken with its little cute cloud.

We didn't have to update any of our other code because BrokenShip extends AbstractShip and has all the same methods as everything else which leaves everything working just as beautifully as before. Blueprint classes for the win!

Leave a comment!

3
Login or Register to join the conversation
yaroslavche Avatar
yaroslavche Avatar yaroslavche | posted 7 months ago | edited

Not able to pass the challenge, since it says, that AbstractDeathStar not found in DeathStarIII. I've tried to require abstract class in concrete, but without luck.
Here is a screenshot: https://ibb.co/W6h8HFH
My code is same as in correct answer, except range value and echo tag in index.php (I've used <?= instead <?php echo).
UPD. Tried again, and it works now. IDK why that happens to me already few times in this course =)

Reply

Sorry about that yaroslavche - we boot up a Docker machine for each challenge instance, and in rare cases (or, for you apparently not so rare :/ ) it somehow gets stuck. Anyways, after about 15 minutes, the challenge machine resets - which is why it works later. But anyways, sorry for the trouble - that's not what we want!

1 Reply
yaroslavche Avatar

Don't worry, everything is fine. At least now I know the reason why this can happen and will wait a bit before complaining in the comments in the future. Thanks for the reply =)

1 Reply
Cat in space

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

userVoice