CS51 - Spring 2010 - Lecture 14
http://www.xkcd.com/810/
summing up the numbers from 1 to some input, n
private int sum(int n){
...
}
- iterative version:
private int sum(int n){
int totalSum = 0;
while( n > 0 ){
totalSum += n;
n--;
}
return totalSum;
}
- procedural recursion
- the recursion we've seen so far is called structural recursion, where we define an object with respect to itself
- in procedural recursion, we define a method with respect to a recursive method call
- recursive version:
- how can we define this recursively (in words)?
- the sum of the numbers from 1...n is n plus the sum of the numbers from 1...n-1
- what is our recursive case?
- sum(n) = n + sum(n-1)
- what is our base case? When do we stop?
- if n is equal to 1, then we know that the sum is 1
- write the method:
private int sum(int n){
if( n == 1 ){
return 1;
} else {
return n + sum(n-1);
}
}
- why does this work?
- first, we call it with n
- we return n plus whatever is returned by sum(n-1)
- which returns n-1 plus whatever is returned by sum(n-2)
- so we get n + n-1 + n-2 + n-3 + ...
- eventually, n == 1 and we return a 1
- so our final sum is: n + n-1 + n-1 + n-3 + ... + 1, which is what we wanted
show
Powers demo
- we want to calculate base to the power n
- how can we do this?
- basic idea is that we want to multiply 1 times base n times
- iteratively:
private double itPower(double base, long n){
double ans = 1.0;
while (n > 0) {
ans = ans * base;
n--;
}
return ans;
}
- recursively:
- how can we define this recursively (in words)? Remember, just assume you have a method that does what you want it to do, but for smaller problems
- the base^n is base times base^(n-1)
- what is our recursive case:
- power(base, n) = base * power(base, n-1)
- what is our base case
- when n == 0 we should just return 1
- alternatively, when n == 1, we could just return base
- either one is fine! what would be the difference?
- write the method:
private double power(double base, long n) {
if (n == 0) {
return 1;
} else {
return base * power(base, n - 1);
}
}
- why does this work?
- first we call it with base and n
- we return base times whatever is returned by power(base, n-1)
- which returns base times whatever is returned by power(base, n-2)
- so we best base * base * base * ...
- eventually, n == 0 and we return 1, so we get:
- base * base * base * ... * base * 1, where base is multiplied n times since each time we reduce n by 1
show
Hanoi demo
- called towers of hanoi
- invented in 1883 by French mathematician Edouard Lucas (
http://en.wikipedia.org/wiki/Tower_of_Hanoi
)
- simple game:
- move the tower from the left side to the right
- you may only move one disc at a time
- you may only place a smaller disc on top of a larger disc
- how do you solve this? Recursion!
- harder to solve iteratively
- how can we define this recursively (in words)?
- to solve the puzzle:
- move the top n-1 discs to the center peg
- move the bottom disk to the right peg
- move the n-1 discs on the center peg to the right peg
- can we generalize this?
- three pegs
- current
- destination
- other
- want to move n discs from current to destination
- move top n-1 discs from current to other
- move bottom disc to destination
- move n-1 discs from other discs to destination
Lab 8: Scribbler
- another recursion lab
- can work in pairs again (e-mail me sooner than later if you'd like a partner, or I can pair you up in the lab, but you'll do your design separately then)
- look at the demo: how are we doing this?
- define a recursive structure, ScribbleCollection, similar to DraggableChain and ChainRection
- what is the recursion in words?
- a ScribbleCollection is a ScribbleIFC, with another ScribbleCollection (rest)
- don't get confused by the fact that Scribble is also a recursive object. Just think of it as any other object.
show
FallingLeaves demo
- we saw this before
- how does it work?
- we have a tree that is an ActiveObject, that generates some number of leaves, which are also ActiveObjects
- Tree class randomly picks between the two different leaf options
- each time we click, we create a new Tree
review
FallingLeaves code
- specifically, look at run method in the Tree class
show
FallingObjects demo
- We now have not only falling leaves, but also falling hail
- How would we modify the code?
- we could try and modify the FallingLeaves class to support the addition of the hail
- this would make the code much more complicated
- would not be good object oriented design
- a better way is to add a new Hail class
- create the Hail class
- change the Tree class to have another random option
- the hail class would look very similar to the FallingLeaf class except with FilledOval instead of a VisibleImage
- if you ever find yourself doing a lot of copy and pasting when programming, there's probably a better way to do it!
inheritance
- Java has what's call class inheritance
- for a class to "inherit" from another class, we use the keyword "extends"
- where have we seen this so far?
- extends WindowController
- extends ActiveObject
- when a class "extends" another class, it inherits the attributes and behaviors from the parent class
- the extending class is called the child class or the subclass
- the class being extended is called the parent class or the superclass
- the subclass inherits all of the attributes from the parent class, that is all of the non-private methods and variables
- private methods are only visible within a class
- this is where the "canvas" variable comes from, we inherit it
- we've seen public and private scopes for variables and methods, for inheritance, we need one more: protected
- why do we need another scoping classification?
- private is only visible within the class
- public is visible to everyone
- protected gives us a middle ground, where they're not visible to everyone, but are visible to subclasses
a simple inheritance example
public class Ball{
public Ball(){
// some code
}
public bounce(){
// some code
}
public setSize(double d){
// some code
}
}
public class BasketBall extends Ball{
public BasketBall(){
// some code
}
public shoot(){
// some code
}
}
- Say we declare a new object of type BasketBall:
BasketBall bball = new BasketBall()
- all of the following would be appropriate:
- bball.shoot()
- bball.bounce()
- bball.setSize(10)
how can we use inheritance to help us in our hail/leaf example?
- look at FallingObject class in
FallingObjects code
- represents a generic falling object
- we use the Drawable2DInterface to allow it the falling object to be a variety of different things
- note that it is protected, why?
- subclasses will need to define the actual object, i.e. with a "new" statement
- constructor just specifies the speed and the stopping height
- run method
- moves the object down the screen and then removes it when it gets to the bottom
- notice that this class does NOT define "object"
- what would happen if we created a new FallingObject?
- we'd get a null pointer exception
- how does this class help us then?
- we can inherit from this class!
- look at FallingLeaf class
- extends FallingObject
- the "super" keyword allows us to call the constructor of the parent, superclass
- must be the first line in the constructor
- create a new VisibleImage and associate it with the "object" variable that we inherited from FallingObject
- where is the run method?
- we don't need one... we inherit it from the FallingObject class
- what will the Hail class look like?
- extends FallingObject
- create a new FilledOval for object (rather than a VisibleImage)
benefits of inheritance
- saves us from having to write code multiple times
- makes shared behavior explicit
- has the code in one place in case we decide to change it
show
FallingObjectsWithTomatoRun demo
- what do we need to change?
- add a Tomato class that extends FallingObject
- can we simply extend FallingObject and use the generic run method?
- the run method in FallingObject removes the object from the canvas when it reaches the bottom
- we want do want to remove the object, but also want to create a "splat" where the tomato lands
- in the run method for Tomato:
- do the normal FallingObject run
- then create a new red FilleOval at the bottom for the splat
- look at Tomato class in
FallingObjectsWithTomatoRun code
- constructor is as we'd expect
- the run method is what is called "overridden"
- when the subclass defines a method with the same name and parameters, the method is overridden
- instead of calling the parents method, it will call the classes method
- often, when we override a method, we just want to alter the behavior of the method
- super.run() calls the run method of the superclass
- in general, super.methodName(), will call methodName of the super class
- what does the run method do?
- calls the run method of the superclass (i.e. FallingObject)
- this will cause the original red, FilledOval to fall and then be removed when it reaches the bottom
- create the splat
show
FallingObjectsWithCows demo
- we've added a two more classes
- Cow (representing the Williams mascot, which is named Ephelia)
- Cecil (representing the Pomona mascot)
- how are these new classes related to the Tomato class?
- like the tomato class, their run method has two stages:
- fall down the screen
- do something when they hit the bottom
- how can we implement these?
- we could do the same thing we did for the Tomato class...
- better way is to add a hitBottom method in the FallingObject class
look at
FallingObjectsWithCows code
- look at the FallingObject class
- we've made an explicit method called hitBottom that simply removes the object from the canvas
- how does this help us?
- classes that extend this class can override that method
- why is it protected?
- if we made it private, then we couldn't override it
- what will the Cecil and Cow classes look like?
- like the others, in the constructor, create a new VisibleImage, etc.
- will only have to override the hitBottom method to change the functionality!
- don't need to override the run method