CS51 - Spring 2010 - Lecture 15
midterm
- average 84
administrative
- keep doing the practice problems
- no lab this week (Friday is a holiday)
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
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 subclass
- the parent class (being extended) is called 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
draw the hierarchy tree for these classes
classes can only extend one class. Why?
- avoid ambiguity
- what if you inherited from two classes that both defined the same method? Which one would be called?
inheritance and types
- which assignment statements do you think are legal?
Cow c;
FallingObject f;
c = new FallingObject(...);
f = new Cow(...);
c = f;
f = c;
- you can use a subclass anywhere you could use the superclass, but NOT vice versa, why?
- In the example above, we know that the cow has at least all of the functionality of a FallingObject, so anywhere we could use a FallingObject, we would use a Cow. The reverse is not true.
- must be able to be figure it out from ONLY looking at that exact statement (i.e. not the history)
FallingObject f = new Cow(...);
Cow c = f; // would not be a valid statement!
- if you know it's true, you can typecast it:
Cow c = (Cow)f; // now it's valid
- the "instanceof" command allows you to ask the boolean question of whether an object is of the specified type
FallingObject f = new Cow(...);
FallingObject f2 = new FallingObject(...);
System.out.println(f instanceof Cow);
- true
System.out.println(f instanceof FallingObject);
- true
System.out.println(f2 instanceof Cow);
- false
System.out.println(f2 instanceof FallingObject);
- true