So it's now time for an Inner Class Challenge.
And just before I actually start typing out what the challenge is.
I've actually grabbed the Link List Challenge,
the final source code from my solution to that link list challenge.
And that's what we're going to be working on.
So if you actually created the solution yourself, and
you've got the code that worked for the linklist challenge, take a copy of that
and save it to another folder, because you're going to be actually changing that.
So what I've done is I've actually grabbed my copy of the solution to
the last video of the last completed solution.
I'm gonna be working on that.
So, what I'm going to do now is actually type in the challenge down the bottom and
we'll actually go about implementing it.
What I'm going to leave all the code that is actually working in the main class,
in the main method, so that we can actually confirm that things are working.
So once I've type this in, I'm gonna run this and then we're gonna make the changes
and run it again to make sure that the changes we made actually work.
So here's what I want you to do in the challenge.
So here is the challenge.
As I mentioned, we're using the Link List Challenge, final solution code.
And from there what we wanna do, is we want you to modify the playlist challenge
code, so that the album class uses an inner class.
So instead of using an array list to hold its tracks,
the album class is gonna be using an inner class, called SongList to do that.
So the inner SongList class will use the ArrayList, and
will provide a method to add a song.
It'll also provide findSong methods which will be used by the containing
Album class to add songs to the playlist.
But neither the Song class or the main class should be changed.
okay so this is future Tim
making an edit to a video where I found
a problem after creating the original
video now the if statement isn't correct
so it actually should be indexed greater
than equal to 0 and index less than
songs dot size so it's basically that
first part the index greater than zero
that actually should be index greater
than equal to zero now remember that
index always starts at zero and it ends
with size take 1 so the problem here is
if we add track number 1 the index will
be 0 and therefore the if statement will
be false because of the way we've got it
testing and that will cause the song
object to be returned as null so in
other words we can't access the first song
basically from track 1 so this is the
reason why we need to greater than an
equal to sign so that we can cover for
the situation where the index is equal
to 0 and in case you want more information
there was a similar problem in the
linked list challenge in this section of
the course and in fact I showed in a
video after that one immediately after
that one and the video for that is
titled bug fix for track 1 error so you
can refer to that for more information
but essentially that's what you need to
do to get this to work replace the
greater than 0 with a greater than equal
to 0 and that will fix that issue
alright so let's move back to the code
So in other words, you should still be able to run it and
do exactly the same thing you could do before in the challenge in the main
class and also the main method, and it should still work after your changes.
So I'm going to actually just quickly run this once just to make sure it still
works.
There is no reason why it shouldn't, but just to be sure, and
I'm just gonna go through, do a couple of things quickly, previous song.
This song is on a playlist, etc.
That's probably enough now.
So I'm gonna actually stop that,
because of course the main thing was that the added font is actually working.
So I'm going to actually complete that to exit out of that there, which I've done.
So at this stage, pause the video and go ahead and
see if you can come back up with the challenge.
And I'll just bring that on the screen again, so you can see what the challenge
is all about, and here, and when you're ready to come back and see what I've done,
start the video again and I'll be here and I'll go through my solution.
Okay, so how did you get out?
Did you figure it out and get it working?
So, let's make a start.
What we're gonna do is, we're gonna need to modify the playlist challenge,
as I mentioned, so that the album class uses an inner class called SongList.
And the SongList class has to have the ability to add a song and
also it's going to have the find song methods as well.
So let's go back into our source code.
And of course, Album is what we're going to be ultimately writing this code.
So what we'll do is, we'll start at the end, within the class,
adding our inner class.
So it's gonna be private class SongList And
we need to have its own array, ArrayList to store the songs.
private ArrayList of Song objects.
Remember we weren't changing the Song class at all.
The constructor for the SongList is going to just be empty, so select none.
And we're gonna just initialize that ArrayList in the constructor,
this.songs = new ArrayList of song objects.
To initialize it, so when it comes time to adding, we can actually do that.
We can actually add those.
We need to add a method now, for adding a song, public boolean add,
and add a song object.
if, songs.contains song.
Return false, otherwise we're going to
do this.songs.add(song), return true, like so.
And we also need our find song methods, and we've been looking at some of
the code up here, you can actually add some of this code.
So let's actually look at our findSong.
I'm gonna copy that one there.
And I'm going to take it out of the Album class, and
I'm gonna paste it in to our inner class.
So we've now got private song, on song, string title.
And it goes through the list of songs, looking for a match.
If it finds a match based on the title, it returns the song.
That it actually failed, otherwise it's gonna return no.
So, the changes would move that functionality find from
the Album class into the songList class.
Likewise, we can also add another function.
The other way that we had it for finding songs, we had find song,
which we took it out of the final solution, but int trackNumber,
where we can put that back in just to be complete.
Int index = trackNumber take one.
You can put if index squared then zero.
Zero and index < songs.size.
Return songs.get, index.
Then otherwise, we return null.
If we weren't able to find a match, because the index was out of range, or
we didn't have that particular entry in there.
So that's our private SongList class.
Nothing particularly complex about it,
other than the fact we've made it in inner class.
So what we now need to do, now that we've done that, we need to make some changes to
the Album class to start using this inner class, this song list.
So one of the first things we'll do, is we're gonna get rid of the array list to
song objects, because that's now handled by our song list class, or inner class.
I'm gonna create a private SongList class and call that songs.
And obviously that means the constructor is now wrong.
Because we dont wanna initialize the array list,
because it's no longer an array list.
This is now a SongList object, so
I'm gonna create new SongList object via the constructor like so.
And addSong,
we are actually going to leave that method in there, cuz that's the public method
that's ultimately gonna be called by the main class and its main method.
So we need to leave that in there, but we need to change the call,
because it's no longer using an internal find song function.
Instead, what we're going to be doing,
is we're just gonna be calling these SongList inner classes add method.
So we're gonna return this.songs.add, and then we'll parse a new
song object to a new Song, which consists of course, of a title and a duration.
Like so and all this other code can now be removed.
Though in terms of the functionality, now of course addSong
is now calling the .add and the .add within our inner class is
actually checking to see whether there's actually a problem there when we add it.
If it contains the song, it returns false.
Otherwise we can try to add it and then we return true.
So in other words, we're still fulfilling this public interface,
this public method for addSong.
But we're getting the songList to actually return true or false.
So that's made the code a bit more compact as a result of that.
Then we actually removed the findList, cuz we didn't need that anymore.
And the next thing we need to do is we need to actually modify the addToPlaylist,
because that, as you can see here that's actually adding or that's actually looking
for the a arraylist to determine if it can add it or not.
So what need to do there is, I'm gonna actually delete some of this code and
we'll do is we'll start and we'll actually do song.
CheckedSong = this.songs.findSong by trackNumber.
So it's now using the inner classes findSong function that we wrote and
then we put if checkSong is not equal to null.
PlayList.add, checkSong, then we return true.
Otherwise this album doesn't have a track number and we're gonna return false.
So really the main thing that we did there is we actually called the inner class to
findSong method, to determine whether it was valid or not.
And then we're just doing pretty well anything else the same as it was before.
So that's the first function.
That's why we're actually returning a track number.
That's why the parameters was a track number and then the playlist to add.
But we can also addToPlaylist by title.
So we need to do the same thing there.
We need to change that reference, so just delete that.
You don't actually change it, it's just a shortcut.
I can actually put songs.findSong.
This time it's gonna be by title.
If checkedSong is not equal to null, we add playlist.AddCheckedSong, return true.
Otherwise, the song plus title is not in this album, which is as that was before.
So, that is literally it.
So it's not particularly difficult in terms of the changes we need to make, but
it's more so
in the thought process that can see that where the functionality should be.
So you can see that we stripped out the arraylist but that was in the Album class,
and also stripped out some of the functionality such as findSong,
Adding songs and so forth, and put that all in the SongList inner class itself.
And then we're actually just doing the calls to those particular methods
as appropriate.
So the last thing now to check is to see that this still works.
If we go back to our main method It should still be able to now run this without
making any changes to the code, and it should still work.
And of course the reason it should still work,
is that all the code was changed internally.
The album class, and as far as what we've exposed as the functionality for
the album class, the exact same methods are still applicable.
And it's still actually there and we're still calling those.
It's just all the functionality had changed internally and
the main method has got no understanding or concept of the fact that we're now
using an inner class instead of the arraylist being in the album class.
And that's one of the beauty is about creating things properly the first time.
We can make these changes internally without affecting
any other part of the application.
So, just to confirm, I can just go through a couple of functions.
Obviously, the sums are there, print out.
So it's obviously finding the song, so it's all working.
So that's actually it.
That's how to go about actually changing out an implementation,
in this case which was a ArrayList.
Which was in the Album class and adding an inner class, which was the SongList class.
So that's it.
So I'll see you in the next section.
We're gonna start talking about Abstract Classes.