Title: Lecture 22: More Inheritance, Searching
1Lecture 22More Inheritance, Searching
2More on Inheritance
- Lets do one more example
- Well redo Laundry with Interfaces
- This time using Inheritance
- Weve done lots of Laundry
- TShirts, Pants
- We modified the Laundry Sorter program so that it
could sort all different kinds - via Laundry Interface, which TShirt and Pants
implemented
3Laundry Interface
public interface Laundry // Move the
laundry relative to its current position //
Parameter // xOffset - distance to move
horizontally // yOffset - distance to move
vertically public void move( double xOffset,
double yOffset ) // Move the laundry to
a new position // Parameter // x -
new x-coordinate // y - new y-coordinate
public void moveTo( double x, double y )
// Remove the laundry from the display
public void removeFromCanvas () //
Return true if the point is in the laundry //
Parameters // pt - the point to test for
containment public boolean contains( Location
pt) // Return the Color of the laundry
item. public Color getColor( ) //
Return the Color of the laundry item. public
void setColor( Color newColor )
- Heres the Laundry interface we used before
- We wrote the bodies of all these methods in
TShirt and Pants - Bodies for all these methods were very similar
- Could we factor the common parts out somehow?
4TShirt, Pants move()
// move the pants by specified offsets. public
void move(double xOffset, double yOffset)
hips.move(xOffset,yOffset)
leftLeg.move(xOffset,yOffset)
rightLeg.move(xOffset,yOffset)
hipTrim.move(xOffset,yOffset)
leftLegTrim.move(xOffset,yOffset)
rightLegTrim.move(xOffset,yOffset)
// move the t-shirt by specified offsets.
public void move(double xOffset, double yOffset )
body.move(xOffset,yOffset)
neck.move(xOffset,yOffset)
sleeves.move(xOffset,yOffset)
bodyTrim.move(xOffset,yOffset)
sleeveTrim.move(xOffset,yOffset)
neckTrim.move(xOffset,yOffset)
- Only difference here is the pieces we move
- Different instance variables per object, but
notice that theyre all Drawable objects in
objectdraw
5TShirt, Pants hide()
//hide the pants public void hide()
hips.hide() leftLeg.hide()
rightLeg.hide() hipTrim.hide()
leftLegTrim.hide() rightLegTrim.hide()
// hide the t-shirt from sight. public void
hide() body.hide() neck.hide()
sleeves.hide() bodyTrim.hide()
sleeveTrim.hide() neckTrim.hide()
- This is almost the same as move()
- Simply delegates to its instance variables
6TShirt, Pants moveTo()
// move the t-shirt to a new upper-left
coordinate position public void moveTo(double
x, double y) move( x - sleeves.getX(), y -
neck.getY())
// move the pants to a specific position.
public void moveTo(double x, double y)
move( x - hips.getX(), y - hips.getY() )
- Only difference here is which shape is used to
determine the upper left corner of the Laundry
7TShirt, Pants contains()
// returns true if the t-shirt contains the
point // false otherwise public boolean
contains(Location pt) return
body.contains(pt) sleeves.contains(pt)
neck.contains(pt)
// returns true if the pants contains the
point //false otherwise public boolean
contains(Location pt) return
hips.contains(pt) leftLeg.contains(pt)
rightLeg.contains(pt)
- Much like the others, these are the same but for
the pieces being compared. - In this case we just test whether some of the
shapes contain the point
8TShirt, Pants getColor(), setColor()
// set color for the shirt public void
setColor(Color newHue) hue newHue
body.setColor(hue) sleeves.setColor(hue)
neck.setColor(hue) // get the sum of the
components // of the shirt's color public
Color getColor() return hue
// set color for the pants public void
setColor(Color newHue) hue newHue
hips.setColor(hue) leftLeg.setColor(hue)
rightLeg.setColor(hue) // get the sum of
the components // of the pant's color public
Color getColor() return hue
- Again, only difference is the pieces of the
object were setting the color on. - Note that getColor() is exactly the same for both
classes.
9What to do?
- We really want to combine this functionality into
one common superclass - Problem
- They have different types of instance variables
- They have different numbers of instance variables
- So what we need is
- Some way to talk to different types variables the
same way - Some way to talk to potentially changing numbers
of such variables - What do we know of that could solve these
problems?
10What to do?
- We know that we can use interfaces to talk to
different types of objects the same way - So we could use DrawableInterface to refer to all
these instance variables - Theyre all drawable objectdraw objects, so they
all implement DrawableInterface - And we know that we can use arrays to hold
varying numbers of objects - We can keep track of how many objects are
actually in the array - When we need to talk to them, we can use a for
loop to send each a similar message
11Putting it all together
- Ill define AbstractLaundry, a generic superclass
for all of our Laundry items, like this - Note that its declared abstract
- This just means it cant be instantiated on its
own - AbstractLaundry can only be used as a superclass
- You can only extend it and construct subclasses
public abstract class AbstractLaundry implements
Laundry
12AbstractLaundry
// The shapes that make up the laundry
private DrawableInterface parts //
max number of parts of laundry private int
maxParts // current number of parts of
laundry private int numParts //
Coordinates of upper-left corner of laundry
private double upperX, upperY // Color of
laundry - black initially private Color hue
new Color(0, 0, 0) // basis for all laundry
constructions // protected so can only be
called by extensions protected
AbstractLaundry( double x, double y, int
maxLaundryParts ) upperX x
upperY y maxParts
maxLaundryParts numParts 0
parts new DrawableInterfacemaxParts
- The constructor and instance variables for
AbstractLaundry are at left - Note that we have an array for all our components
- Constructor remembers
- Upper left corner
- max number of parts
13AbstractLaundry addComponent()
// add a component to laundry item protected
void addComponent(DrawableInterface newPart)
if (numParts lt maxParts)
partsnumParts newPart
numParts
- This method is declared protected so only
subclasses can use it - It allows the subclass to add shapes to the
AbstractLaundry whatever shapes they want - All are stored in the array and managed together
by AbstractLaundry.
14Using AbstractLaundry
- Lets try to make a TShirt class now
- Hopefully its easier than before
- We shouldnt have to write nearly as many methods
- Declare like this
- Now what do we do?
public class TShirt extends AbstractLaundry
15TShirt constructor
- Implementing different kinds of laundry is simple
now - we can just add all the pieces in the subclass
constructor - Heres a TShirt (without constants shown)
- Hey, this isnt so bad. We no longer have to
write a bunch of tedious methods theyre managed
for us! All we do is put in the shapes.
//Create a new shirt at the specified
location. public Tshirt( double x, double y,
DrawingCanvas canvas ) super (x, y,
numTShirtParts) // Construct background
trim addComponent(new FramedRect( x, y
SIZE, SLEEVE_WIDTH, SLEEVE_HEIGHT, canvas ))
addComponent(new FramedRect( x BODY_INSET, y
SIZE, BODY_WIDTH, BODY_HEIGHT, canvas ))
// construct interior (except neck)
addComponent(new FilledRect( x1, ySIZE1,
SLEEVE_WIDTH-1, SLEEVE_HEIGHT-1, canvas ))
addComponent(new FilledRect( xBODY_INSET1,
ySIZE1, BODY_WIDTH-1, BODY_HEIGHT-1, canvas
)) // add neck and neck trim
addComponent(new FilledOval( x NECK_INSET, y,
NECK_WIDTH, NECK_HEIGHT, canvas ))
addComponent(new FramedOval( x NECK_INSET, y,
NECK_WIDTH, NECK_HEIGHT, canvas ))
16AbstractLaundry Final Words
- You can probably imagine how to implement Pants
- Take a look at how its done, along with the
AbstractLaundry methods, in the
InheritanceLaundry example program on the web
site - What did we just do?
- We used all the tools for abstraction that weve
learned about this semester to make a really
general class - AbstractLaundry can describe almost any kind of
movable shape - Does so using power of interfaces, arrays, and
inheritance - Lots to think about here! Be sure its straight
in your head how this is working
17AbstractLaundry Final Words
- You can think of abstract superclasses like
AbstractLaundry as code that you write for
programmers - By writing AbstractLaundry, weve made our own
lives easier by - reducing the task of creating new graphical
objects to an almost declarative process - We just declare shapes we want to combine in
the constructor by calling their constructors and
calling addComponent() - The imperative part, or the how of moving,
hiding, contains(), etc, is left up to the
computer! - This is a pretty powerful technique, in that you
can express a great variety of objects with not a
lot of code
18Searching
- New Topic Searching
- Searching is, simply, looking for something
- When do you search in real life?
- Search for phone numbers?
- Search through your address book?
- What about on a computer?
19Searching on a Computer
- Some examples
- Finding a particular number in an array
- Finding a scribble that contains the point where
the mouse is - Youve done this already!
- Finding your SSN in a database
- Searching for the String Fred in your Word
documents - Finding Amino Acid sequences in strands of DNA
- Searching the web
20Finding scribbles
- Weve done some searching this semester
- We searched recursively through a list of
scribbles for one that contained a particular
point - Remember the contains method?
public boolean contains(Location point) if
(first.contains(point)) return true
if (!rest.isEmpty()) return
rest.contains(point) return false
21Searching for a Scribble
Does this scribble contain the point?
- Run through the list and test each element to see
if it contains the point - Return an element if it does contain the point.
22Searching for a Scribble
Does this scribble contain the point?
- Run through the list and test each element to see
if it contains the point - Return an element if it does contain the point.
23Searching for a Scribble
Does this scribble contain the point?
- Run through the list and test each element to see
if it contains the point - Return an element if it does contain the point.
24Searching for a Scribble
Does this scribble contain the point?
- Run through the list and test each element to see
if it contains the point - Return an element if it does contain the point.
25Searching for a Scribble
Does this scribble contain the point?
- Run through the list and test each element to see
if it contains the point - Return an element if it does contain the point.
26How much work did that take?
- Well estimate the amount of work that a search
takes by figuring out - how many places did we have to look?
- We say that n is the total number in the list or
data set that were searching - Well express the amount of work (the number of
places we need to look) in terms of n
27How much work did that take?
- In the case of the list of scribbles, we had a
total of 4 scribbles in our data set, so n 4. - Calling contains() is what we do to check a
scribble, or to look in a particular place - If we assume that a scribble that contains the
point were looking for has an equal chance of
being at any position in the list - Then the search takes n/2 calls to contains() on
average, when it is successful - If its unsuccessful, it takes n calls to
contains() - So this is, in the worst case, n steps
28Disadvantage of Lists
- Lists dont allow fast arbitrary access to
elements - If we want to get at one, weve got to step
through the list one element at a time - You cant jump right to the end, or to any place
in the middle without traveling over all the
preceding elements - This is inefficient, because it takes a lot of
work to iterate over all the elements - So were going to switch to arrays, as we can
access them wherever we want, and fast! - From here on, Ill talk about searching in arrays
29Searching an array of ints
5
3
4
9
0
2
1
7
8
6
0
1
2
3
4
5
6
7
8
9
- Suppose Ive got an array of integers and I want
to find one in it. - Ill define a method like this
- What should the body look like?
public int search(int array, int num)
30Searching an array of ints
5
3
4
9
0
2
1
7
8
6
0
1
2
3
4
5
6
7
8
9
- Suppose Ive got an array of integers and I want
to find a number, call it num, in the array. - Ill define a method like this
public int search(int array, int num)
for (int index 0 index lt array.length
index) if (arrayindex num)
return index
return -1
31Searching an array of ints
public int search(int array, int num)
for (int index 0 index lt array.length
index) if (arrayindex num)
return index
return -1
- Suppose that num is 0
- Well search for it, starting at element 0
- is array0 0?
32Searching an array of ints
public int search(int array, int num)
for (int index 0 index lt array.length
index) if (arrayindex num)
return index
return -1
- Suppose that num is 0
- Well search for it, starting at element 0
- is array1 0?
33Searching an array of ints
public int search(int array, int num)
for (int index 0 index lt array.length
index) if (arrayindex num)
return index
return -1
- Suppose that num is 0
- Well search for it, starting at element 0
- is array2 0?
34Searching an array of ints
public int search(int array, int num)
for (int index 0 index lt array.length
index) if (arrayindex num)
return index
return -1
- Suppose that num is 0
- Well search for it, starting at element 0
- is array3 0?
35Searching an array of ints
public int search(int array, int num)
for (int index 0 index lt array.length
index) if (arrayindex num)
return index
return -1
- Suppose that num is 0
- Well search for it, starting at element 0
- is array4 0?
- YES! Well return 4, to tell whoever called us
where the number we were looking for was found.
36Searching an array of ints
public int search(int array, int num)
for (int index 0 index lt array.length
index) if (arrayindex num)
return index
return -1
- If we went all the way to the end, wed stop when
we fell off the end - Returning -1 indicates that we didnt find
anything in the array
37Recursive search
public int recSearch(int array, int num, int
start) if (start gt array.length)
return -1 else if (arraystart num)
return start else return
recSearch(array, num, start 1)
- We can write the search that we used before
recursively, instead of using a for loop - Makes the various cases clearer
- Can you see how this does exactly the same thing?
38Searching an ordered array
- Suppose our array looks like the one above, in
that all of its elements are in order - And suppose we search for 11
- What happens?
39Searching an ordered array
- Suppose our array looks like the one above, in
that all of its elements are in order - And suppose we search for 11
- What happens?
- The search goes all the way to the end, but finds
nothing. It returns -1.
40Searching an ordered array
- What do we know when we reach 12, though?
- Well, we searched for 11
- 12 is greater than 11
- And the elements of the array are in order
- We know during the search that if the current
number is greater than what were looking for,
that the search will fail - we wont find num, well just return -1
41Searching an ordered array
- We can thus rewrite search like this, if we know
were searching an ordered array - This new condition bails out and returns -1 when
weve passed where num should be
public int recSearch(int array, int num, int
start) if (start gt array.length)
return -1 else if (arraystart num)
return start else if (arraystart gt
num) return -1 // num will not appear
in rest of array since it is sorted. else
return recSearch(array, num, start 1)
42How much work?
- If we assume that the numbers well search for
are evenly distributed around the median of the
array, then - It should take, on average, n/2 steps of work for
both successful and unsuccessful searches - In the worst case, though, we search for
something thats at or past the end of the array - Still worst case n steps of work
43Linear Search
- These searches are called linear searches
- This is because the number of steps it takes to
solve them is a linear function of the number of
elements in the list youre searching - That is
- number of steps a n b
- for some constants a and b
- n number of elements in the list
- In our case, were pretty much talking about when
the amount of work for n elements is either n or
n/2 steps. - Can we do less work than this?
44Can we do better than this?
- How do you search for names in a phonebook?
- You know theyre in order
- Where do you start?
- Do you start at the beginning, then look at every
page until youve either found or passed the name
youre looking for? - Probably not
- You probably start somewhere in the middle, then
skip around
45Guessing numbers
- Well play a guessing game
- Ill think of a number between 1 and 100
- You try to guess it, and Ill say either
- Too High or
- Too Low
- Well see how many guesses it takes
- Essentially youre searching for a number between
1 and 100 - Depending on how good you are at this, it could
take a while. - Dont worry, well stop before you end up missing
the rest of lecture.
46Guessing numbers
- What did you do?
- If youre good at this, you probably tried to
eliminate as many numbers as you could each turn - To do this, youd start in the middle
- What number am I thinking of?
- 50?
- too low.
- 75?
- too high.
- 62?
- too low.
- 68?
- Yes.
47Process of elimination
- If you know the array is sorted and you start in
the middle, then you know you can eliminate half
of the items on the first check - If Im looking for 4 above, and I discover that
10 is in the middle of the array - I can eliminate the whole right-hand side,
because I know 4 cant possible be there - Then can act like Im just searching the left
half of the array - Do the same thing to the left half! Start in its
middle
48Process of elimination
0
3
4
7
10
12
89
105
106
200
0
1
2
3
4
5
6
7
8
9
- Now we operate on the left half of the array
- Check the middle of it
- Remember, were trying to see if the array
contains 4 - Is 3 less than or greater to 4?
- Less than!
- We can now eliminate half of whats remaining,
just like before - This time eliminate the left-hand side of the
remaining array from consideration
49Process of elimination
0
3
4
7
10
12
89
105
106
200
0
1
2
3
4
5
6
7
8
9
- Now weve reduced our search to two squares, and
this is only the 3rd step! - Now what?
- Were looking for 4, and we found 4 at index 2.
- We return 2, to let the caller know where we
found 4. - Done!
50Binary search
- The process we just went through is called binary
search - Its called a divide conquer algorithm because
it divides the problem in half at each step - First step is whole array, next is 1/2 of it,
next is 1/4 of that, next is 1/8 of that, etc.b - This makes time to solution MUCH faster!
- Heres Binary Search in Java
public int binarySearch(int array, int num, int
low, int high) if (low gt high)
return -1 else int mid (low
high) / 2 if (arraymid num)
// num is same as middle number return
mid else if (num lt arraymid)
// num is smaller than middle number
return binarySearch(array, num, low, mid - 1)
else // num is larger than middle
number return binarySearch(array, num,
mid 1, high)
51Wrapping Binary Search
- Binary search, as written, is inconvenient
- We have to provide a low and a high value when we
call it - but usually these are going to be 0 and
array.length - 1 - Can solve this by providing a helpful search()
method with two parameters that just calls the
binarySearch() method with low and high set
appropriately
public int binarySearch(int array, int num, int
low, int high)
public int search(int array, int num)
return binarySearch(array, num, 0, array.length -
1)
52How much work is it?
- Each step, we cut the portion we need to search
in half. - How many times can divide number in half before
you get to 1? - If you start with n, you divide to get n/2 then
n/4, n/8, ... and eventually get 1. - Let's suppose that n2k, then divide to 2k-1,
2k-2, 2k-3, ..., 20 1 divide k times by 2. - In general, you can divide n by 2 at most k times
to get to 1, where k log2(n). - So this is, in the worst case, log2(n) steps of
work
53Compare to linear search
- Its not so significant at first, but as the
number of elements gets larger, youre doing much
less work - For 1 million elements, linear search could have
to check all 1,000,000 - Binary Search only has to check 20!
- Caveat remember that binary search only works if
your numbers are sorted! - Well learn how to be sure they are put that way
next time.