Bummer! This is just a preview. You need to be signed in with a Basic account to view the entire video.
Start a free Basic trial
to watch this video
Let's return to Dale's Diner and see how we can complete our model of his business by creating an additional custom class. We'll put our property attributes to work, introduce custom init methods and review "dot" and "self" syntax.
-
0:00
When we last checked in,
-
0:01
we were deciding how we can add the items that a diner orders to their TableCheck.
-
0:06
To do that, we said we'd need two things, a way to model the menu item and
-
0:10
then a process to add that menu item to the check.
-
0:13
Let's begin with the first.
-
0:16
So what kind of variables could we use to model a menu item?
-
0:20
Well an NSString would be great for the item's name, like cheeseburger.
-
0:24
But it wouldn't be able to hold the price of the item which would be afloat and
-
0:27
that's important.
-
0:29
Also what if we wanted to add an attribute,
-
0:31
like a bool of comes with fries.
-
0:33
Seems like we'd need a collection to keep all that information bundled together.
-
0:38
The obvious choice would be an NSDictionary since that can hold
-
0:41
key value pairs of different data types.
-
0:44
Now for this very simple example we probably could create
-
0:47
NSDictionary objects for each of our menu items.
-
0:50
But what happens when we want to add some functionality or
-
0:53
property that doesn't conform to NSDictionary?
-
0:55
We might find that really limiting.
-
0:57
So what do we do?
-
0:59
Well, if you read the title of this video you probably know the answer.
-
1:02
We're going to create our own custom class.
-
1:06
So here I am back inside dalesDiner,
-
1:08
the Xcode project that is, anyway we said we want to create a custom class.
-
1:12
So let's make that happen.
-
1:13
File > New > File, and in OS X we can pick
-
1:18
Cocoa Class, we'll be very creative and
-
1:23
we'll call it MenuItem, and we can create it.
-
1:29
Now what kind of things will a menu item contain?
-
1:33
Here in our header, we'll want a name for the item like cheeseburger.
-
1:37
So let's give ourselves an NSString property.
-
1:46
And we can call it, itemName.
-
1:52
Next, we'll want a float for the price.
-
2:01
We can call that itemPrice, and remember floats are primitives.
-
2:07
They don't need a memory directive like strong or weak, so
-
2:10
nonatomic is all we are going to need inside those parentheses.
-
2:15
What else might we want?
-
2:16
Well, what about a bool to tell if it's food or beverage?
-
2:20
Restaurants always want to know how much of their revenue is drink,
-
2:23
since the marginal profit on drinks is so high.
-
2:26
So let's create one.
-
2:35
All right I think we have what we need in our MenuItem class, but
-
2:38
we don't need to worry too much we can always come back here if we decide we want
-
2:41
some additional functionality.
-
2:44
So let's head back to our main.m and
-
2:46
see if we can add some menu items to our table check.
-
2:50
Okay so here we are, and
-
2:52
we can see when we left off we had created a TableCheck called table1.
-
2:57
We had assigned a subtotal, a tip, and we'd marked it as TakeOut.
-
3:02
But we haven't added any menu items.
-
3:04
So our customers aren't gonna be too happy about paying $15 for nothing.
-
3:08
Let's see if we can fix that.
-
3:09
Firstly, we'll need to create a MenuItem object.
-
3:13
Okay, let's do that down here.
-
3:17
We'd start by saying menuItem, hey, I'm not getting the code completion I want.
-
3:22
What's going on?
-
3:23
That's right.
-
3:24
We didn't import it yet.
-
3:26
Let's go over, or rather let's go up and
-
3:29
we can type import MenuItem.
-
3:34
All right, there we go.
-
3:35
Now let's try it again.
-
3:37
See, we're getting our auto complete there.
-
3:39
We'll call our first MenuItem grilledCheese,
-
3:45
and we can say MenuItem alloc.
-
3:52
Great, no errors.
-
3:55
We do get this one warning here.
-
3:58
But that's just saying that the variable is unused, grilledCheese.
-
4:01
We haven't done anything with it yet, and that's fine.
-
4:04
So we could add this to our TableCheck but
-
4:06
this MenuItem variable is just named grilledCheese.
-
4:10
The menu item itself has no values, so let's give it some.
-
4:14
First of all we can give it a name,
-
4:19
we can say, grilledCheese.itemName = Grilled Cheese.
-
4:29
Next we'll probably wanna give it a price.
-
4:32
I think $4.50 is a fair price for
-
4:34
grilledCheese, we can do on the instance of the class called grilledCheese.
-
4:40
We'll say grilledCheese.itemPrice = 4.50.
-
4:49
So just to review we created a MenuItem with the variable
-
4:54
name grilledCheese using alloc and init.
-
4:57
Then after that we set the itemName to grilledCheese and
-
5:01
we did that using the dot syntax here.
-
5:05
And then we set the itemPrice, again using the dot syntax, to 4.50.
-
5:09
If we had wanted to, you could also set it like this,
-
5:13
grilledCheese setValue for
-
5:17
whichever key we'd like to do, but that's not nearly as easy, so we won't do that.
-
5:22
Now just for practice let's create ourselves another menu item.
-
5:25
Let's say MenuItem is gonna be soupDuJour.
-
5:30
And we'll set that equal.
-
5:35
To MenuItem alloc init, and of course that will create our instance for
-
5:40
us and below that we'll set some properties.
-
5:44
So we'll say soupDuJour.itemName = @"Soup
-
5:49
Du Jour" cuz that's what it's called.
-
5:57
For you sticklers out there I believe the d is not capitalized.
-
6:02
What's a fair price for soup?
-
6:04
I think we can probably say, how about $3.25?
-
6:10
Okay.
-
6:14
Now it's worth noting in real life you'd probably have dozens or
-
6:17
hundreds of menu items like this.
-
6:19
So we probably would store these values in a database or p list.
-
6:23
We wouldn't create them right here in the body of our code but
-
6:26
that's way beyond the scope of this video, so we're just doing that here.
-
6:30
In addition we've given ourselves some magic numbers the 4.50, the 3.25.
-
6:36
We're gonna leave them in for now and not spend a lot of time creating other
-
6:38
variables since you know not to leave them hanging around in a real project.
-
6:43
Okay, let's give ourselves a little more space and
-
6:46
let's see if we can add those items to our TableCheck.
-
6:49
We had the foresight to create a mutable array called ItemsOrdered.
-
6:53
So it should be easy to add these items to the array.
-
6:56
Let's just go ahead and do it.
-
6:59
We could say that table1, that's the instance of our table check,
-
7:03
.itemsOrdered.
-
7:05
That's the array, and we want to add an object.
-
7:08
And what do we want to add?
-
7:10
Well let's add a grilled cheese.
-
7:12
Okay, cool.
-
7:13
No errors, no problem.
-
7:15
Let's run it and see what happens.
-
7:18
Okay, let's mouse over table1.
-
7:22
Pop it open.
-
7:23
Okay, $15, 5 for the tip.
-
7:27
Items ordered equals nil.
-
7:30
Just in case we'll look into the NSArray.
-
7:33
No, I don't see any grilled cheese in there.
-
7:36
What is going on?
-
7:38
The array is nil.
-
7:40
Pause the video for a moment and
-
7:42
try to figure out why the mutable array didn't hold our value and it's set to nil.
-
7:48
It's a tough one but it's worth thinking about.
-
7:52
Okay, did you give it some thought?
-
7:54
The reason we couldn't add a value to our NS mutable array
-
7:58
is that we never created the empty array, but wait.
-
8:02
Then why could we assign values to our other properties like the subtotal
-
8:06
and the tip?
-
8:08
Well those properties are primitive types specifically floats and
-
8:11
they don't need to be allocated.
-
8:14
Okay that makes sense, but then how about these strings?
-
8:18
Those are objects too.
-
8:20
We didn't allocate for them.
-
8:22
Well that's right we didn't, but we did use the literal syntax and
-
8:26
that takes care of the ALEC for us.
-
8:29
Okay so we know we left out a step.
-
8:32
How can we fix it?
-
8:34
Well, one way to do it would be for us to alloc the array like this.
-
8:38
We could say that table1.itemsOrdered
-
8:44
equals NSMutableArray, alloc init.
-
8:49
And then we close it off.
-
8:51
We've still got our break point, so let's run it again.
-
8:54
And see if that worked.
-
8:57
Okay if we mouse over table1, we can open it up, and
-
9:02
now we see that our items order does have one object and
-
9:07
it is a Grilled Cheese for $4.50.
-
9:10
A little expensive but it's doable.
-
9:13
Okay, so this works, but it doesn't really feel right.
-
9:19
It seems too manual.
-
9:21
Why should we have to tell each table check to allocate memory for
-
9:24
its itemsOrdered array?
-
9:26
I mean, the most important part of the table check is keeping track of what
-
9:29
the customer orders, right?
-
9:30
It seems like this should be ready to go after we alloc and init our table check.
-
9:35
This is a tough one.
-
9:36
But pause the video for another second and
-
9:39
think about where in our code we could fix this issue for all future table checks.
-
9:47
Well, like I said, this is a tough one.
-
9:49
What you would want to do is customize the init method of the TableCheck class
-
9:54
to automatically alloc the items ordered array.
-
9:57
Now, we haven't written any custom methods.
-
9:59
We haven't even written any methods at all.
-
10:02
But as a sneak peek, let's create one now and talk through it.
-
10:05
Then in our next video, we'll go whole hog on the topic of methods.
-
10:10
So, let's head over to TableCheck.m, and if we didn't
-
10:14
do anything then we could call init on this class like we're currently doing.
-
10:19
It'll automatically use the init method defined inside NSObject
-
10:23
since that's our superclass.
-
10:25
See if we switch to the .h here we see that TableCheck is a subclass of NSObject.
-
10:31
Remember when we subclass an object, it inherits the attributes and
-
10:35
functionality of its superclass, unless we specify otherwise, all right.
-
10:39
Well it's time to specify otherwise, we'll head back to that .m, and
-
10:44
then we'll begin typing out our new init method.
-
10:59
Now let's walk through that code, but again this is just a sneak peek so
-
11:03
we won't dissect absolutely everything.
-
11:05
What we're saying is let's define a method called init that can return any type.
-
11:12
That's what the id means right here.
-
11:14
Init is a method that our superclass already has,
-
11:17
our superclass of course is NSObject.
-
11:20
So we're creating a custom version of it now.
-
11:23
Inside the curly braces, we're creating an instance of TableCheck,
-
11:28
and then we're using the superclasses init method.
-
11:32
Then provided that the self, that is, the instance already exists, we're saying that
-
11:39
itemsOrdered, the NSMutableArray should now be allocated and inited.
-
11:45
Then we're gonna return a copy of self that is the TableCheck instance.
-
11:51
I know that was a mouthful, and
-
11:53
I absolutely don't want you to get bogged down in this syntax.
-
11:56
On the contrary, I just wanted to show this code since it touches on so
-
12:00
many of the different concepts and conventions which need to come together in
-
12:04
order to begin working in an object oriented manner.
-
12:07
We've got our custom class TableCheck inheriting from its superclass NSObject.
-
12:12
Here we're using the superclasses version of init inside our own custom init method.
-
12:20
We do this specifically because we want to allocate
-
12:24
an NSMutableArray called itemsOrdered.
-
12:27
That's very important,
-
12:29
because then it'll be ready to use after we init any instance of TableCheck.
-
12:36
The big headline is, we just changed the class TableCheck, so that every
-
12:41
instance of that class we create will now be improved per our specification.
-
12:47
Specifically, its itemsOrdered array will be alloc-ed and ready to rock.
-
12:53
If we want all orders to be assumed to come with fries right at the start,
-
12:58
we could put code inside our custom init, like this.
-
13:02
Self.comesWithFries = YES.
-
13:07
Now, we're going to get an error here,
-
13:09
because we didn't create a property for that.
-
13:11
But you see what I'm getting at.
-
13:13
That would make sure that when we create any new instance of a class,
-
13:16
that bool would automatically be set to YES.
-
13:20
Okay, let's hop back to our main.
-
13:24
We're going to comment out this line right here where we manually alloced
-
13:28
itemsOrdered and we'll run it again.
-
13:36
We can mouse over our TableCheck and here again we see itemsOrdered 1 object and
-
13:44
it should be a $4.50 Grilled Cheese, very good.
-
13:49
Now just to drive the point home, let's stop the program.
-
13:54
Let's drop a breakpoint in here before we init TableCheck.
-
13:58
We'll put one in down here as well and
-
14:00
then we'll put one in inside our custom init method.
-
14:05
Let's run our code again and see what happens.
-
14:10
Okay our code stops before we can alloc and init,
-
14:13
let's continue and see what happens.
-
14:17
We wind up inside the init method for TableCheck.
-
14:22
So it's going and finding its own init method because we created one.
-
14:26
Had we not created one, it would have just used the NSObject init method.
-
14:30
We continue down here, and we can see that table1.
-
14:37
Has its array, doesn't have any objects yet, but we have alloced and
-
14:41
inited our array.
-
14:42
If we go one more step, we'll now see that
-
14:48
an object has been added, see now we have one object inside itemsOrdered.
-
14:53
But you know while we're here, why don't we get rid of these plugs up here and
-
14:57
actually add to the subtotal using the item prices and menu items were adding.
-
15:03
We could do that down below like this.
-
15:05
Table1.subtotal += grilledCheese.itemPrice
-
15:12
because that's the property that contains the price.
-
15:19
Next, we could say, table1.itemsOrdered
-
15:25
addObject:soupDuJour.
-
15:30
And we can add that price too.
-
15:44
We'll get rid of these breakpoints up top, we don't need those.
-
15:50
And we'll run our code again.
-
15:55
You don't need any of these brackets here.
-
15:59
Now we'll run our code again.
-
16:03
And we can get rid of the breakpoint in our init.
-
16:07
All right here we go.
-
16:08
Now if we look at table1, we can see our subtotal is 7.75,
-
16:13
it's adding as we go that's 3.25 plus 4.50.
-
16:20
But something doesn't smell right.
-
16:22
And I'm not talking about Dale's seafood platter.
-
16:25
These four lines right here, they seem repetitive, and I think we can do better.
-
16:30
So, we figured out how to add properties to the custom classes we've created.
-
16:34
Then we learned how to give those properties values using the dot syntax.
-
16:37
We even got an introduction to customizing or overriding a super classes method.
-
16:42
Heck, we even added instances of one of our custom classes, MenuItem,
-
16:46
to another of our custom classes, TableCheck.
-
16:50
But we ended on sort of a sour note.
-
16:52
We had those four lines where we repeated the same functionality twice.
-
16:56
I feel like we could probably create something a bit more elegant to add
-
16:59
menu items and prices to the table check.
-
17:03
What on earth could we use?
-
17:05
It seems like there should be some method to perform
-
17:08
this type of function in our code.
-
17:10
I know I stumbled on a solution like this once,
-
17:13
in fact it's right on the tip of my tongue.
-
17:17
I know it's.
You need to sign up for Treehouse in order to download course files.
Sign up