CPSC 111
Introduction to Computation
Introduction to Computation
November 17
rd, 2009
Department of Computer Science Undergraduate Events
Events this week
Technical Interview Skills Workshop
Workshop Leader: Sabina Nawaz CSSS Movie Night
Movies: The Hangover & Star Trek Date: Mon., Nov 16 Time: 5 – 6:30 pm Location: FSC 1005, 2424 Main Mall Movies: The Hangover & Star Trek Date: Thurs., Nov 19 Time: 6 ‐ 10 pm Location: DMP 301 CS Distinguished Lecture Series Speaker: Glenn Entis Date: Thurs Nov 19
Cool Things: Entrance FREE! One FREE popcorn and pop for every attendee! ‘ Date: Thurs., Nov 19 Time: 3:30 ‐ 4:50 pm Location: DMP 110 Cranium and Board Games Night – ‘Byte to Eat’ Fundraising Date: Fri., Nov 20 Time: 5 – 6 pm Masters of Digital Media Program Info Session Date: Thurs., Nov 19 Time: 5 – 6 pm Time: 5 6 pm Location: X‐Wing Undergraduate Student Lounge Time: 5 6 pm Location: X‐Wing Undergraduate Student Lounge.
Administrative Stuff
Assignment 3 is coming up (keep an eye on
Vista)
Vista)
We are trying hard to have the marks for your
We are trying hard to have the marks for your
midterm 2 ready this week
Unlikely that you’ll get the exam papers this
week
Administrative Stuff
Big reading in Big Java 3rd edition:
Chapter 1 1 through 1 8 (introduction) Chapter 1.1 through 1.8 (introduction) Chapter 2.1 through 2.10 (using objects)
Chapter 3.1 through 3.8 (implementing classes) Chapter 4 (data types)
Chapter 4 (data types) Chapter 5.1 through 5.4 (decisions) Chapter 6.1 through 6.5 (iteration) Chapter 7.1, 7.5, 7.6, 7.7 (arrays) Chapter 14.1, 14.3 (searching and sorting) Chapter 8.1 through 8.9 (designing classes) Chapter 9.1, 9.2, 9.3 (interfaces and polymorphism) Chapter 10 (inheritance) Chapter 2.11, 2.12 (simple graphics) Chapter 9.5, 9.6, 9.7, 9.8, 10.9, 10.10 (event handling d hi l i t f ) and graphical user interfaces)
Administrative Stuff
Big reading in Big Java 2nd edition: Ch t 1 1 th h 1 8 (i t d ti ) Chapter 1.1 through 1.8 (introduction) Chapter 2.1 through 2.10 (using objects) Chapter 3.1 through 3.8 (implementing classes) Chapter 4 (data types)Chapter 4 (data types) Chapter 6.1 through 6.4 (decisions) Chapter 7.1 through 7.5 (iteration) Chapter 8.1, 8.5, 8.6, 8.7 (arrays)p , , , ( y ) Chapter 19.1, 19.3 (searching and sorting) Chapter 9.1 through 9.9 (designing classes) Chapter11.1, 11.2, 11.3 (interfaces and polymorphism) Chapter 13 (inheritance) Chapter 5.1, 5.2 (simple graphics) Chapter 11.5, 12.1, 12.2, 12.3 (event handling d h l f ) and graphical user interfaces)
So where are we?
So where are we?
•
We learned
We learned
– programming language basics – about classes – about conditionals (if statements) – about loopsp – about arrays – Sorting and searching efficiently•
We started looking at how we can reuse our
code: one of the main strengths of OOP
OOP is reuse
Object‐oriented programming is largely about reuse. OOP lets us reuse a class definition to create lots of instances (objects) of that class. Otherwise, we'd be writing the same program over and over and over. (we have seen this) But OOP also lets us reuse class definitions to help with the creation of new, related but different class definitions (inheritance). ( ) OOP even lets us use incomplete class definitions to help with the creation of other class definitions. That also makes it so that we don't have to write more code than we need to (interfaces). Why is this important? It saves us (programmers) a lot of time h ' i th d l t d i t f bi when we're managing the development and maintenance of big software projects.Roller Coaster flashback
O fi t ti f ll t li it d i i l t d f ti lit
Our very first generation of roller coasters were limited in simulated functionality: folks could board roller coasters, but I had no way to let riders get off. That is, the simulated roller coasters had board() methods, but no empty() methods.
public class RollerCoaster{ private int numberOfRiders; private int capacity;
public RollerCoaster(int aCapacity) { numberOfRiders = 0;
capacity = aCapacity;
System.out.println("Another ride is ready to go!"); }
}
//we also had another constructor with no parameters // but we’ll ignore it for this discussion
public void board() {
if (numberOfRiders < capacity) { numberOfRiders = numberOfRiders+1; System.out.println("Welcome on board!"); } else{ else{
System.out.println("Sorry, the coaster’s full"); } }}
Roller Coaster flashback
An evolutionary step beyond these primitive roller coasters is the class of roller An evolutionary step beyond these primitive roller coasters is the class of roller coasters that let people get off. These new roller coasters were exactly the same as their predecessors in all other respects.
public class RollerCoaster2{ public class RollerCoaster2{ private int numberOfRiders; private int capacity;
public RollerCoaster2(aCapacity) { numberOfRiders = 0;
capacity = aCapacity;
System.out.println("Another ride is ready to go!"); }
public void board() {
if (numberOfRiders < capacity){ numberOfRiders = numberOfRiders+1; System.out.println("Welcome on board!"); } } else{
System.out.println("Sorry, the coaster’s full"); }
} }
public void empty() { numberOfRiders = 0;
Now, at this point I have
• RollerCoaster, which has a board() method, and
• RollerCoaster2, which is identical, with the same board() method, but also has a empty() method
has a empty() method.
We saw that we can use the two classes together to create roller coasters of these two different types in the same method
coasters of these two different types in the same method Not necessarily bad, but not very efficient, nor scalable. For example, both RollerCoaster and RollerCoaster2 have copies of exactly the same board() method. • What if I later find out that there's a bug in board()? • I have to fix it twice. The problem grows if I create other classes from the basic Roller Coaster class
The better way (a first pass)
public class ShinyRollerCoaster extends RollerCoaster {
}
What does that do?
We just created a new class called ShinyRollerCoaster that inherited most non‐static methods and non‐static variables from the RollerCoaster class. To enhance ShinyRollerCoaster beyond this, we just add the additional variables and methods that we want but that aren't included in the RollerCoaster class. Inheritance is the process by which a new class is derived from an existing one. It is a fundamental principle or defining characteristic of object‐oriented i programming.
Inheritance and Constructors
The subclass (or child class) inherits all methods except constructor methods from the superclass (or parent class).
To use the constructor methods from the superclass, we need to use the To use the constructor methods from the superclass, we need to use the reserved word super.
public class ShinyRollerCoaster extends RollerCoaster {
{
public ShinyRollerCoaster(int aCapacity) {
super(aCapacity);}}
The reserved word super, in the context of a constructor method for a subclass, tells Java to use the appropriate constructor method of the subclass, tells Java to use the appropriate constructor method of the superclass.
Let’s see how it works
public class ShinyThemePark {
public static void main( String[] args ) {
System.out.println("Building my theme park");
ShinyRollerCoaster thunderbolt = new ShinyRollerCoaster(2);
RollerCoaster flightDeck = new RollerCoaster(2); thunderbolt.board();
thunderbolt.board();
//thunderbolt.empty();// not defined yet thunderbolt.board();
flightDeck.board(); flightDeck.board(); }
}
Building my theme park
A 2 person ride is ready to go A 2 person ride is ready to go Welcome on board!
Welcome on board!
Sorry, the coaster’s full Welcome on board!
So where are we?
So where are we?
•
We learned
– programming language basics – about classes b t diti l (if t t t ) – about conditionals (if statements) – about loops– about arraysabou a ays
– Sorting and searching efficiently
•
Today we’ll
– Talk a bit more about inheritance – Take a look at another construct that allows for code reuse: interfaces reuse: interfacesThe better way (a third pass)
Let’s finally refine our ShinyRollerCoaster class to include the empty() method
public class ShinyRollerCoaster extends RollerCoaster {
public ShinyRollerCoaster(int aCapacity)
p y ( p y)
{
super(aCapacity); }
public void empty () {
numberOfRiders = 0; }}
}}
Oops
Let’s finally refine our ShinyRollerCoaster class to include the empty() method
public class ShinyRollerCoaster extends RollerCoaster {
public ShinyRollerCoaster(int aCapacity)
p y ( p y)
{
super(aCapacity); }
public void empty () {
numberOfRiders = 0; }}
}}
¾Error: ShinyRollerCoaster.
java:11: numberOfRiders has private access in RollerCoaster
The better way (a third pass)
Let’s finally refine our ShinyRollerCoaster class to include the empty() method
public class ShinyRollerCoaster extends RollerCoaster {
public ShinyRollerCoaster(int aCapacity)
p y ( p y)
{
super(aCapacity); }
public void empty () { numberOfRiders = 0; }} }} The subclass will inherit all the non‐static variables of the superclass, but the access control on private variables is so tight that a subclass won't be able to directly access an inherited private variable
The better way (a third pass)
public class RollerCoaster{ private int numberOfRiders; private int capacity;
private int capacity;
public RollerCoaster(int aCapacity) { numberOfRiders = 0;
capacity = aCapacity;
S t t i tl ("A th id i d t !")
System.out.println("Another ride is ready to go!"); }
The simple way to fix this problem is to go back to the The simple way to fix this problem is to go back to the
definition of the superclass and change the access modifier to
protected.
A protected variable can be directly accessed by the class where it is declared and any classes derived from that classy .
The better way (a third pass)
public class RollerCoaster{
protected int numberOfRiders;
protected int capacity;
protected int capacity;
public RollerCoaster( int aCapacity) { numberOfRiders = 0;
capacity = aCapacity;
S t t i tl ("A th id i d t !")
System.out.println("Another ride is ready to go!"); }
The simple way to fix this problem is to go back to the The simple way to fix this problem is to go back to the
definition of the superclass and change the access modifier to
protected.
A protected variable can be directly accessed by the class where it is declared and any classes derived from that class.y
The better way (a third pass)
public class RollerCoaster{
protected int numberOfRiders;
protected int capacity;
protected int capacity;
public RollerCoaster( int aCapacity) { numberOfRiders = 0;
capacity = aCapacity;
S t t i tl ("A th id i d t !")
System.out.println("Another ride is ready to go!"); }
Using the protected variable here solves that last problem Using the protected variable here solves that last problem
Can you think of another solution?
( i fi bli h d f b f id i h
(Hint: Define a public setter method for numberOfRiders in the RollerCoaster class – that method will be inherited by the
Questions?
With that glimpse of Chapter 10 (13 in 2nd edition) in
mind let's go back and see what Chapter 9 (11 in 2nd
mind, let s go back and see what Chapter 9 (11 in 2nd
OOP is reuse
Object‐oriented programming is largely about reuse. Reuse saves us (programmers) a lot of time when we're managing the
d l t d i t f bi ft j t
development and maintenance of big software projects.
OOP lets us reuse a class definition to create lots of instances (objects) of that class Otherwise we'd be writing the same (objects) of that class. Otherwise, we d be writing the same program over and over and over. (we have seen this) But OOP also lets us reuse class definitions to help with the p creation of new, related but different class definitions (inheritance, which we just saw). OOP even lets us use incomplete class definitions to help with the creation of other class definitions. That also makes it so that we don't have to write more code than we need to (interfaces, we’ll don t have to write more code than we need to (interfaces, we ll
Building a better theme park
Building a better theme park
Let's say that you've been inspired by CPSC 111 and decide design your own game competitor for Roller decide design your own game competitor for Roller Coaster Tycoon. To beat the competition, you want a game that simulates Roller coasters, but you’ll also want other ride types, including rides you can’t imagine right now…
For example you may want to include For example, you may want to include...
Water rides
Water rides...
Thrill rides
Thrill rides...
and let’s not forget kiddie rides!
...and let s not forget kiddie rides!
A more varied theme park
A more varied theme park
Would it make sense to start with an existing Roller Coaster class and extend it to become a Water Ride Coaster class and extend it to become a Water Ride class? Not so much. Nor would it make better sense to start with a Water Ride class and extend it to become a Roller Coaster class. Wh t k i t k l d th t th What makes more sense is to acknowledge that the Water Ride and the Roller Coaster share attributes of a common generic Ride
A more varied theme park
A more varied theme park
So why not just write a generic ride class definition and extend it twice once for the Roller Coaster class and extend it twice ‐‐ once for the Roller Coaster class and once for the Water Ride class? Somebody might try to make an instance of a generic ride, and we don't want generic ride objects in our theme park. What are they? What fun are they? How can they make us money? What can we do? Here's one answer...
Interfaces
Informally, we've used the word "interface" to refer to the set of public methods (for example, getters and setters)
set of public methods (for example, getters and setters) through which we interact with an object.
There's also a more formal use of the word interface in Java.
A Java interface is a collection of constants and abstract methods that constrains how related classes must be
methods that constrains how related classes must be implemented.
Interfaces
An abstract method has no implementation...no body. It's just a method header followed by a semicolon.
It specifies how one communicates with a method, but not what the method does.
Interfaces
public interface Ride { public void board(); public int seatsLeft(); public int getNumRiders(); public void empty(); }We create an interface by using the reserved word interface in what
ld b th l h d if i t f l
would be the class header, if an interface were a class
(which it's not...think of it more as the syntactic specification for a class).
Interfaces
public interface Ride {
public abstract void board(); public abstract int seatsLeft();
public abstract int getNumRiders(); public abstract void empty();
p p y();
}
We could use the reserved word abstract in the abstract method headers, but we don't have to because the
Interfaces
public interface Ride { void board(); int seatsLeft(); int getNumRiders(); void empty();p y(); } Also, methods in an interface type are automatically , yp y public, so we don't really need the public modifier.Interfaces
An interface is not a class. An interface only prescribes what methods some other class or classes must have. That is, an interface specifies the headings for methods th t t b d fi d i l th t i l t th that must be defined in any class that implements the interface… …but it doesn't say what happens inside the methods. from Absolute Java by Walter Savitch.Implementing an interface
A class implements an interface by providing method
implementations for each of the abstract methods defined implementations for each of the abstract methods defined in the interface.
A class that implements an interface uses the reserved word implements followed by the interface name in the
l h d
Implementing an interface
public class RollerCoaster2008 implements Ride {
private int numberOfRiders; private int numberOfRiders; private int capacity; public RollerCoaster2008(int aCapacity){ numberOfRiders = 0; capacity = aCapacity; System.out.println("Another roller coaster is ready to go!"); }} public int getNumRiders(){ return numberOfRiders; }} public void empty(){ numberOfRiders = 0; } …
Implementing an interface
… public void board(){ if (numberOfRiders < capacity) {{ numberOfRiders = numberOfRiders+1; System.out.println("Welcome on board the roller coaster!"); } else { System.out.println("Sorry, the coaster’s full"); }} } bli i t t L ft(){ public int seatsLeft(){ return capacity ‐ numberOfRiders; } }Implementing an interface
public class WaterRide2008 implements Ride {
private int numberOfRiders; private int numberOfRiders; private int capacity; public WaterRide2008( int aCapacity){ numberOfRiders = 0; capacity = aCapacity; System.out.println("Another water ride is ready to go!"); }} public int getNumRiders(){ return numberOfRiders; }} public void empty(){ numberOfRiders = 0; } …
Implementing an interface
… public void board(){ if (numberOfRiders < capacity) {{ numberOfRiders = numberOfRiders+1; System.out.println("Welcome on board the water ride!"); } else { System.out.println("Sorry, the water ride is full"); }} } bli i t t L ft(){ public int seatsLeft(){ return capacity ‐ numberOfRiders; } }Implementing an interface
For a class to implement an interface, it must provide a definition for all methods in the interface.
definition for all methods in the interface.
If there are unimplemented methods, the class must be declared to be an abstract class, but that's a topic for another day.
What do these relationships look like?
Ride i l t i l t implements implements RollerCoaster 2008 WaterRide 2008 KiddieRide 2008 ThrillRide 2008 extends EvenCooler RollerCoasterWhy this stuff is very very cool*
Because an object of a class that implements an interface is also an object of that interface type.
is also an object of that interface type. This concept is the basis of an important object‐oriented programming principle called polymorphism. P l hi i d i d f th d f t l d Polymorphism is derived from the word fragment poly and the word morpho in Greek, and it literally means "multiple forms" forms . *assuming you come from the planet Nerdtron
Why this stuff is very very cool
Polymorphism simplifies the processing of various objects in the same class hierarchy by using the same method call in the same class hierarchy by using the same method call for any object in the hierarchy.
We make the method call using an object reference of the interface.
At run time, the Java Virtual determines which class in the hierarchy the object actually belongs to and invokes the
hierarchy the object actually belongs to and invokes the version of the method implemented for that class.
Why this stuff is very very cool
public class ThemePark2008 {
public static void main(String [] args) public static void main(String [] args) {
Ride foo1 = new RollerCoaster2008(42);
Ride foo2 = new WaterRide2008(42); f b d() foo1.board(); foo2.board(); } }} Another roller coaster is ready to go! Another water ride is ready to go! W l b d th ll t ! Welcome on board the roller coaster! Welcome on board the water ride!
Why this stuff is very very cool
public class ThemePark2008 {
public static void main(String [] args) public static void main(String [] args) {
Ride foo1 = new RollerCoaster2008(42);
Ride foo2 = new WaterRide2008(42); f b d() foo1.board(); foo2.board(); } }} The little foos may look like Ride objects to you and me. But Java knows the difference and finds the appropriate method for each foo. That makes our programming job a lot easier to do. Why?
Why this stuff is very very cool
Because the alternative is to write lots of chunks of code that look like sort of like this (if they were written in
if we want to get on the ride foo1 and foo1 is a RollerCoaster2008
( y English): if we want to get on the ride foo1 and foo1 is a RollerCoaster2008 then print “welcome on board the roller coaster" else if we want to get on the ride foo1 and foo1 is a WaterRide2008 then print “welcome on board the water ride" else if we want to get on the ride foo1 and foo1 is a ThrillRide2008 then print " welcome on board the BOO! Thrill Ride" else if we want to get on the ride foo1 and foo1 is a KiddieRide2008… As the number of classes within the same hierarchy grows, so does the size of the chunks of code represented above. Eeyow!