Student: I’m still feeling a little shaky on methods and method definitions.
Prof: Let’s do another example, this time from our examples from images. We saw a French flag 🇫🇷, and we can easily imagine other tri-color flags like Italy 🇮🇹, Ireland 🇮🇪, and so on. Defining all of them involves a lot of code, we keep having to define new stripes and using the
Beside composition to put them together. Let’s look at that first because the pattern will tell us something useful.Prof: What patterns do you notice?
Student: Well, the composition is exactly the same in all of them, it’s just the colors that change.
Prof: Just the colors?
Student: Oh right, and big france has numbers different, too.
Prof: Right! Let’s turn these examples into a
record and a repeatable way to draw them. I’m going to suggest a breakdown – let’s first make a record that stores just the three colors.Student: OK, that is nice, but where are the pictures?
Prof: That’s what we’ll use a method for. Instead of writing all those
Beside and Rect constructor uses over and over, we’ll write it once in the method body. In the method we’ll have all the colors (left, middle, right) available. What other information do we need?Student: The sizes? Like the 10s and 20s and 30s and 60s and stuff.
Prof: Right. OK so let’s think through what that means for the method header. It is going to need to take in the width and the height. And we want to produce the
Pict. What are the pieces of a method header?Student: Um… the return type, the name, the parameters
Prof: Great. What should the return type be?
Student: An image?
Prof: Great, a
Pict. What do you want to call the method?Student: drawflag?
Prof: Sure. I’ll write it as
drawFlag. Then the parameters?Student: width, height
Prof: What types?
Student: Ummm I guess
int?Prof: OK great, put that all together
Student:
Pict drawFlag(int width, int height)Prof: Looks great. So our code so far would look like this, but I won’t put a run button in because it won’t run yet:
record Tricolor(String left, String middle, String right) {
Pict drawFlag(int width, int height)
}
Tricolor fr = new Tricolor("blue", "white", "red");
Tricolor it = new Tricolor("green", "white", "red");
Tricolor ir = new Tricolor("green", "white", "orange");Student: Why won’t it run?
Prof: It doesn’t have a method body yet. It needs us to fill in the way to compute the return value from the fields and parameters.
Student: How do we do that?
Prof: Well, one thing I like to do is look at our earlier examples, and see which pieces correspond to which fields and which parameters. Here’s one way I look at it – all of the examples had this shape:
new Beside(new Rect(__, __, __),
new Beside(new Rect(__, __, __), new Rect(__, __, __)));All the positions I replaced with __ could change. Then I need to fill them back in with the names of a field or parameter.
Student: So like, the fields will go where the colors were? And the width and height for the sizes?
Prof: That’s right.
Student: Alright, let me see… the first part would be like
new Rect(width, height, left), right?Prof: Yup, you’re getting it. The
left is one of the fields and the width and height are the parameters.Student: OK, here goes
Student: Huh? I thought I had it
Prof: You followed my instructions too exactly! Good work but a little off. This method body is for
returning a new image every time it’s called so we need to make sure it’s returned with that keyword.Student: OK, I see, so the error was saying that there wasn’t a
return statement. We always have to have one?Prof: Yes, for the most part – a method needs to
return something of the right type. Go ahead and make the change, and also try calling the method on some of your example data to see what we get!Student: OK let’s see…
Practice
Many flags are striped the other way. Here is a record for them, with the method body already written using
Above. Write the method header (the body uses parameters named width and height), then define nlPic as the Netherlands flag 30 wide and 20 tall, and dePic as the German flag at any size you like.record HorizontalTricolor(String top, String middle, String bottom) {
{
return new Above(new Rect(width, height, top),
new Above(new Rect(width, height, middle),
new Rect(width, height, bottom)));
}
}
HorizontalTricolor nl = new HorizontalTricolor("red", "white", "blue");
HorizontalTricolor de = new HorizontalTricolor("black", "red", "yellow");
{
return new Above(new Rect(width, height, top),
new Above(new Rect(width, height, middle),
new Rect(width, height, bottom)));
}
}
HorizontalTricolor nl = new HorizontalTricolor("red", "white", "blue");
HorizontalTricolor de = new HorizontalTricolor("black", "red", "yellow");