cs 112 introduction to programming critters/event-driven programming; interface yang (richard) yang...
TRANSCRIPT
CS 112 Introduction to Programming
Critters/Event-Driven Programming; Interface
Yang (Richard) YangComputer Science Department
Yale University308A Watson, Phone: 432-6400
Email: [email protected]
2
Admin
PS8 and class project questions? Special session on Google App Engine Monday 8 pm at DL 120
Recap: The Critter Class
// abstract class means not implement every methodpublic abstract class Critter { public boolean eat() public Attack fight(String opponent) // ROAR, POUNCE, SCRATCH, FORFEIT public Color getColor() public Direction getMove(String[][] grid) // NORTH, SOUTH, EAST, WEST, CENTER public String toString() … // read the class for other methods available}
Recap: Event-Driven Programming Key concepts:
The simulator is typically implemented using polymorphism
The simulator is in control, NOT an animal.• An animal must keep state (as fields) so that it can make a single move, and know what moves to make later.
• We say that EDP focuses on writing the callback functions of objects
%%
Next move?
Recap: Cougar
Write a critter class Cougar (among the dumbest of all animals):Method Behavior
constructor
public Cougar()
eat Always eats.
fight Always roars.
getColor Blue if the Cougar has never fought; red if he has.
getMove Walks west until he finds food; then walks east until he finds food; then goes west and repeats.
toString "C"
State Machine Driven Cougar
6
MoveWest
MoveEast
eat()
eat()
getMove
Color
! Hasfought
Hasfought
fight()
Recap: Snake
Method Behavior
constructor
public Snake()
eat Never eats
fight random pounce or roar
getColor Color(20, 50, 128)
getMove 1 E, 1 S; 2 W, 1 S; 3 E, 1 S; 4 W, 1 S; 5 E, ...
toString "S"
Non-EDP Version
A non-event driven version
cycleLength = 1; while (true) { steps = 0; while (steps < cycleLength) if cycleLength % 2 == 1
go East else go West steps ++; go South cycleLength ++ }
Non-EDP-> EDP: Guarding Condition
9
steps < cycleLength
if (cycleLength % 2 == 1) go Eastelse go Weststeps++;
steps == cycleLength
go SouthcycleLength ++steps=0;
A non-event driven version
cycleLength = 1; while (true) { steps = 0; while (steps < cycleLength) if cycleLength % 2 == 1
go East else go West steps ++; // invariant? go South cycleLength ++ }
Snake solutionimport java.awt.*; // for Color
public class Snake extends Critter { private int cycleLength; // # steps in curr. Horiz. cycle private int steps; // # of cycle's steps already taken public Snake() { cycleLength = 1; steps = 0; } public Direction getMove() { if (steps < cycleLength) {
steps++;
if (cycleLength % 2 == 1) {
return Direction.EAST;
} else {
return Direction.WEST;
}
} else {
steps = 0;
cycleLength ++;
return Direction.SOUTH;
}
} public String toString() { return "S"; }}
steps < cycleLength
if (cycleLength % 2 == 1) go Eastelse go Weststeps++;
steps == cycleLength
Go SouthcycleLength ++steps=0;
Comment: States
Counting is helpful: How many total moves has this animal made? How many times has it eaten? Fought?
Remembering recent actions in fields may be helpful: Which direction did the animal move last?
• How many times has it moved that way? Did the animal eat the last time it was asked? How many steps has the animal taken since last
eating? How many fights has the animal been in since last
eating?
Testing critters
Focus on one specific critter of one specific type Only spawn 1 of each animal, for debugging
Make sure your fields update properly Use println statements to see field values
Look at the behavior one step at a time Use "Tick" rather than "Go"
Designing Bulldog Be open minded Think about strategies, e.g.,
How much state do your bulldogs keep and probe state?
When does your Bulldog eat/mate? Is there an “optimal” fight strategyfor a specific type of opponent?
Do your bulldogs play disguise? Does your strategy change with time? Do your bulldogs coordinate their behaviors to form some kind of patterns?
13
Coordination
14
https://www.youtube.com/watch?v=_sUeGC-8dyk
Coordination
15
Critter exercise: Hipster A group of hipster critters want to hangout together
Each hipster can suddenly become inspired and choose a random board location called an edgy bar
A hipster go north until reaches edgy bar’s horizontal, then east until reaching the bar
Solution 1 (See Hipster.java)
public class Hipster extends Critter { private Random rand; private int edgyBarX, edgyBarY; private int nextT, t; private final int FLASH_INTERVAL = 200; public Hipster() { rand = new Random(); t = 0; nextT = rand.nextInt(FLASH_INTERVAL); } public Direction getMove(String[][] grid) { t ++; if (t == nextT) { edgyBarX = rand.nextInt( getWidth() ); edgyBarY = rand.nextInt( getHeight() ); t = 0; nextT = rand.nextInt(FLASH_INTERVAL); } if (getY() != edgyBarY) { return Direction.NORTH; } else if (getX() != edgyBarX) { return Direction.EAST; } else { return Direction.CENTER; } } public String toString() { return "H(" + edgyBarX + "," +edgyBarY + ")”; }
Solution 1 (See Hipster.java)
public class Hipster extends Critter { private Random rand; private int edgyBarX, edgyBarY; private int nextT, t; private final int FLASH_INTERVAL = 200; public Hipster() { rand = new Random(); t = 0; nextT = rand.nextInt(FLASH_INTERVAL); } public Direction getMove(String[][] grid) { t ++; if (t == nextT) { edgyBarX = rand.nextInt( getWidth() ); edgyBarY = rand.nextInt( getHeight() ); t = 0; nextT = rand.nextInt(FLASH_INTERVAL); } if (getY() != edgyBarY) { return Direction.NORTH; } else if (getX() != edgyBarX) { return Direction.EAST; } else { return Direction.CENTER; } } public String toString() { return "H(" + edgyBarX + "," +edgyBarY + ")”; }
Problem: Each hipster goes to a different bar.We want all hipsters to share the same bar location.
Solution 1 (See Hipster.java)
public class Hipster extends Critter { private Random rand; private static int edgyBarX, edgyBarY; private int nextT, t; private final int FLASH_INTERVAL = 200; public Hipster() { rand = new Random(); t = 0; nextT = rand.nextInt(FLASH_INTERVAL); } public Direction getMove(String[][] grid) { t ++; if (t == nextT) { edgyBarX = rand.nextInt( getWidth() ); edgyBarY = rand.nextInt( getHeight() ); t = 0; nextT = rand.nextInt(FLASH_INTERVAL); } if (getY() != edgyBarY) { return Direction.NORTH; } else if (getX() != edgyBarX) { return Direction.EAST; } else { return Direction.CENTER; } } public String toString() { return "H(" + edgyBarX + "," +edgyBarY + ")”; }
Recall: Static members
static: Part of a class, rather than part of an object. Object classes can have static methods and
fields. Not copied into each object; shared by all
objects of that class.
classstate:private static int staticFieldAprivate static String staticFieldBbehavior:public static void someStaticMethodC()public static void someStaticMethodD()
object #1
state:int field1double field2
behavior:public void method3()public int method4()public void method5()
object #2
state:int field1double field2
behavior:public void method3()public int method4()public void method5()
object #3
state:int field1double field2
behavior:public void method3()public int method4()public void method5()
Accessing static fields From inside the class where the field was
declared:
fieldName // get the valuefieldName = value; // set the value
From another class (if the field is public):
ClassName.fieldName // get the valueClassName.fieldName = value; // set the value
generally static fields are not public unless they are final
22
Example
We want to assign a unique, increasing employee ID for each Employee object (e.g., Secretary, Marketer, Lawyer) that we create
Employee with Staticpublic class Employee { private String name; private int empID; private static int nextEmpID = 1000;
public Employee(String name) { this.name = name; empID = nextEmpID; nextEmpID++; } public static int nextEmpID() { return nextEmpID; } …}
public class Firm {
public static void main(String[] args) { Lawyer larry = new Lawyer(“Larry"); Marketer mike = new Marketer("Mike"); Lawyer lynn = new Lawyer(”Lynn");
}}
24
Example: The Employee Objects
Employee.nextEmpID
1000
public class Employee { private String name; private int empID; private static int nextEmpID = 1000;
public Employee(String name) { this.name = name; emplID = nextEmpID; nextEmpID++; } …}
25
Example: The Employee Objectslarry: Lawyer
name = “Larry”empID = 1000; Employee.nextEmpID
10001001
public class Employee { private String name; private int empID; private static int nextEmpID = 1000;
public Employee(String name) { this.name = name; emplID = nextEmpID; nextEmpID++; } …}
26
Example: The Employee Objectslarry: Lawyer
name = “Larry”empID = 1000;
mike: Marketer
name = “Mike”empID = 1001;
Employee.nextEmpID
10011002
public class Employee { private String name; private int empID; private static int nextEmpID = 1000;
public Employee(String name) { this.name = name; emplID = nextEmpID; nextEmpID++; } …}
Back to Hipsterpublic class Hipster extends Critter { Random rand; private static int edgyBarX, edgyBarY; private int nextT, t; public Hipster() { rand = new Random(); t = 0; nextT = rand.nextInt(200); } public Direction getMove(String[][] grid) { t ++; if (t == nextT) { edgyBarX = rand.nextInt(60); edgyBarY = rand.nextInt(50); t = 0; nextT = rand.nextInt(200); } if (getY() != edgyBarY) { return Direction.NORTH; } else if (getX() != edgyBarX) { return Direction.EAST; } else { return Direction.CENTER; } } public String toString() { return "H(" + edgyBarX + "," +edgyBarY + ")”; }
Exercise
Design a type of critters that can conduct formation, e.g., move around a circle with equal distance (enough to earn you full 20 points of Part 2/PS8)
Comment: PS8 Development Strategy
Do one species at a time in ABC order from easier to harder debug printlns
Simulator helps you debug smaller width/height fewer animals "Tick" instead of "Go" "Debug" checkbox drag/drop to move animals
Summary: Polymorphism
polymorphism: Ability for the same code to be used with different types of objects and behave differently with each.
System.out.println can print any type of object.• Each one displays in its own way on the console.
CritterMain can interact with any type of critter.• Each one moves, fights, etc. in its own way.
Polymorphic Array: Generic Programming
index
0 1 2 3
Critter[] critters = {new Ant(),
new Cougar(),
new Snake(),
new Bulldog()
}
while (true) {
for (i=0; i<critters.length; i++)
pos = critters[i].getMove();
disp = critters[i].toString();
draw disp at pos
Not dependent on any specific critters but only the generic
Critter concept
32
Single vs. Multiple Inheritance Some object-oriented languages allow multiple inheritance, which allows a class to be derived from two or more classes, inheriting the members of all parents
The price: collisions, such as the same variable name, same method name in two parents, have to be resolved
Java design decision: single inheritance, meaning that a derived class can have only one parent class
But many concepts in real-life do have multiple perspectives
Motivating Example: Sorting
33
public static void insertionSort(int[] elems) {
for (int index = 1; index < elems.length; index++) {
int key = elems[index];
int insertPos = index;
while (insertPos > 0 && elems[insertPos - 1] > key) {
// shift larger values to the right
elems[insertPos] = elems[insertPos - 1];
insertPos--;
}
elems[insertPos] = key;
} // end of for
} // end of insertionSort
Motivating Example: Sorting Employees
34
public static void insertionSort(int[] elems) {
for (int index = 1; index < elems.length; index++) {
int key = elems[index];
int insertPos = index;
while (insertPos > 0 && elems[insertPos - 1] > key) {
// shift larger values to the right
elems[insertPos] = elems[insertPos - 1];
insertPos--;
}
elems[insertPos] = key;
} // end of for
} // end of insertionSort
Goal: design a sorting method tosort Employee objects by name.
Q: Which line(s) of sorting depend on int instead of Employee
Motivating Example: Sorting Employees
35
public static void insertionSort(Employee[] elems) {
for (int index = 1; index < elems.length; index++) {
Employee key = elems[index];
int insertPos = index;
while (insertPos > 0 && elems[insertPos - 1].compareTo(key) >0 ) {
// shift larger values to the right
elems[insertPos] = elems[insertPos - 1];
insertPos--;
}
elems[insertPos] = key;
} // end of for
} // end of insertionSort
public class Employee { private String name;
int compareTo(Employee other) { return name.compareTo(other.name); }
Motivating Example: Sorting Persons
36
public static void insertionSort(Person[] elems) {
for (int index = 1; index < elems.length; index++) {
Person key = elems[index];
int insertPos = index;
while (insertPos > 0 && elems[insertPos - 1].compareTo(key) >0 ) {
// shift larger values to the right
elems[insertPos] = elems[insertPos - 1];
insertPos--;
}
elems[insertPos] = key;
} // end of for
} // end of insertionSort
public class Person { private int age;
int compareTo(Person other) { return age – other.age; }
Applying Sorting to General Class X
37
public static void insertionSort(X[] elems) {
for (int index = 1; index < elems.length; index++) {
X key = elems[index];
int insertPos = index;
while (insertPos > 0 && elems[insertPos - 1].compareTo(key) >0 ) {
// shift larger values to the right
elems[insertPos] = elems[insertPos - 1];
insertPos--;
}
elems[insertPos] = key;
} // end of for
} // end of insertionSortApplies to any class X that
has implemented the compareTo method
38
Summary The sort method can be applied to any class X that implements the compareTo method that we used when defining the sort method.
Q: Implement using already covered technique Define a base class Xpublic class X { public int compareTo(X other); }
Define that Employee, Person, … extends X and overrides compareTo
Problem: An Employee/Person… conceptually really is not an X. X is just an abstract property.
39
Interface
An interface provides an abstraction to write reusable, general programs
Instead of writing a program for a single class of objects, we want to write a program to handle all classes with a given set of behaviors/properties An interface is an abstraction for the common behaviors of these behaviors
Often interface represents abstract concepts
40
Outline
Admin and recap Interface
Motivation Syntax
41
Interfaces
interface: A list of methods that classes can promise to implement.
Analogous to non-programming idea of roles or certifications• "I'm certified as a CPA accountant. The certification assures you that I know how to do taxes, perform audits, and do management consulting."
42
Inheritance vs Interface
Inheritance gives you an is-a relationship and code-sharing. A Lawyer object can be treated as an Employee, and Lawyer inherits Employee's code.
Interface give you an is-a relationship without code sharing.
43
Interface Syntax
An interface is a collection of constants and abstract methodsabstract method: a method header without a method body; we declare an abstract method using the modifier abstract
since all methods in an interface are abstract, the abstract modifier is usually left off
44
Interface: Example
public interface Movable {
public double getSpeed(); public void setSpeed(double speed); public void setDirection(int direction); public int getDirection();}
interface is a reserved wordinterface is a reserved word
No method in anNo method in aninterface has a definition (body)interface has a definition (body)
A semicolon follows each method headerA semicolon follows each method headerimmediatelyimmediately
This interface describes the behaviors common to all
movable things.(Every Movable thing should
have these methods.)
45
Implementing an interface general syntax:
public class <name> implements <interface names> { ...}
Example: public class Bicycle implements Movable { ...}
(What must be true about the Bicycle class for it to compile?)
46
Interface Implementation
If we write a class that claims to be an interface (e.g., Movable) , but doesn't implement all of the methods defined in the interface, it will not compile.
Example:public class Bicycle implements Movable {}
The compiler error message:Bicycle.java:1: Bicycle is not abstract and does not override abstract method getSpeed() in Movable
47
Example: Shape interface
An interface for shapes:
public interface Shape { public double area();}
This interface describes the common features that all shapes should have in your design.(Every shape has an area.)
48
Example: Circle class
// Represents circles.public class Circle implements Shape { private double radius; // Constructs a new circle with the given radius. public Circle(double radius) { this.radius = radius; } // Returns the area of this circle. public double area() { return Math.PI * radius * radius; } }
49
Example: Rectangle class
// Represents person.public class Person implements Shape { private double weight; private double height; …
public Person(double weight, double height) { this.weight = weight; this.height = height; }
// Returns the area of a person using Du Bois formula public double area() { return 0.007184 * Math.power(weight, 0.425)
* Math.power(height, 0.725); } // other methods}
50
Outline
Admin and recap Interface
Motivation Syntax Polymorphism through interface
Polymorphic Reference through Interface
A variable of interface type T can hold an object of any class implementing T.
Movable mobj = new Bicyle();
You can call any methods defined in the Movable interface on mobj.
When you invoke a method through the interface variable, the behavior is that of the object type.
52
Interface Polymorphism: Example
public static void printShapeInfo(Shape s) { System.out.println("area : " + s.area()); System.out.println();}
Any object that implements the interface may be passed as the parameter to the above method.Circle circ = new Circle(12.0);Person john = new Person(60, 175);printShapeInfo(circ);printShapeInfo(john);
53
Interface Polymorphism: Example We can create an array of an interface type, and store any object implementing that interface as an element.
Circle circ = new Circle(12.0);Person john = new John(60, 175);YaleStudent nicole = new YaleStudent();
Shape[] shapes = {circ, john, nicole};for (int i = 0; i < shapes.length; i++) { printShapeInfo(shapes[i]);}
Each element of the array executes the appropriate behavior for its object when it is passed to the printShapeInfo method
Highly Reusable Sorting
54
public interface Comparable {public int compareTo(Comparable comp);
}
public class Sort { public static void insertionSort(Comparable[] elems) { for (int index = 1; index < elems.length; index++) { Comparable key = elems[index]; int insertPos = index; while (insertPos > 0 && elems[insertPos - 1].compareTo(key) > 0) { // shift larger values to the right elems[insertPos] = elems[insertPos - 1]; insertPos--; }
elems[insertPos] = key;
} // end of for } // end of insertionSort}
Defining a Comparable Interface
55
public interface Comparable {public int compareTo(Comparable comp);
}
public class Employee extends Object implements Comparable {private String name;
public Employee(String name) {this.name = name;
}
public int compareTo(Comparable emp) {String oName = ((Employee)emp).name();return name.compareTo( oName );
}…}
Defining a Comparable Interface
56
public public class Staff { private Employee[] staffList; public Staff() { staffList = new Employee[4]; staffList[0] = new Lawyer("Lisa"); staffList[1] = new Secretary("Sally"); staffList[2] = new LegalSecretary("Lynne"); staffList[3] = new Hourly("Holly", 100); } public void payday() { Sort.insertionSort(staffList); for (int count = 0; count < staffList.length; count++) { System.out.printf("%-10s: ", staffList[count].name()); System.out.printf("$%.2f\n", staffList[count].pay() ); } }}
57
Exercise
What if you want the ability to sort according to different attribute, e.g., name, pay
Highly Reusable Sorting
58
public interface Comparable2 {public int compareTo(Comparable2 comp, String attr);
}
public class Sort { public static void insertionSort(Comparable2[] elems, String attr) { for (int index = 1; index < elems.length; index++) { Comparable2 key = elems[index]; int insertPos = index; while (insertPos > 0 && elems[insertPos - 1].compareTo(key, attr) > 0) { // shift larger values to the right elems[insertPos] = elems[insertPos - 1]; insertPos--; }
elems[insertPos] = key;
} // end of for } // end of insertionSort}
Defining a Comparable Interface
59
public class Employee extends Object implements Comparable2 {private String name;
public Employee(String name) {this.name = name;
}
public int compareTo(Comparable emp, String attr) { if (attr.equals(“name”)) { String oName = ((Employee)emp).name();
return name.compareTo( oName ); else if (attr.equals(“pay”)) { double diff = pay() – ((Employee)emp).pay(); if (diff > 0) return 1; else return -1; } else return 0;
} …}
public interface Comparable2 {public int compareTo(Comparable comp, String attr);
}
Summary: Using Interface for General Programming
When defining a class or method (e.g., sorting), think about the essence (most general) properties/behaviors of the objects you require
Define those properties in an interface
Implement the class/method for the interface only so that your design is the most general !
60