600 likes | 681 Views
CS 112 Introduction to Programming. Critters/Event-Driven Programming; Interface Yang (Richard) Yang Computer Science Department Yale University 308A Watson, Phone: 432-6400 Email: yry@cs.yale.edu. Admin. PS8 and class project questions? Special session on Google App Engine
E N D
CS 112 Introduction to Programming Critters/Event-Driven Programming; Interface Yang (Richard) Yang Computer Science Department Yale University 308A Watson, Phone: 432-6400 Email: yry@cs.yale.edu
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 method public 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):
State Machine Driven Cougar • getMove • Color eat() fight() eat() MoveWest ! Hasfought MoveEast Hasfought
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 steps < cycleLength 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 ++ } if (cycleLength % 2 == 1) go East else go West steps++; steps == cycleLength go South cycleLength ++ steps=0;
Snake solution steps < cycleLength import 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"; } } if (cycleLength % 2 == 1) go East else go West steps++; steps == cycleLength Go South cycleLength ++ 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?
Coordination https://www.youtube.com/watch?v=_sUeGC-8dyk
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) • Problem: Each hipster goes to a different bar.We want all hipsters to share the same bar location. 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 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 + ")”; }
class state:private static int staticFieldAprivate static String staticFieldB behavior: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() 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.
Accessing static fields • From inside the class where the field was declared: fieldName// get the value fieldName = value; // set the value • From another class (if the field is public): ClassName.fieldName// get the value ClassName.fieldName = value; // set the value • generally static fields are not public unless they are final
Example • We want to assign a unique, increasing employee ID for each Employee object (e.g., Secretary, Marketer, Lawyer) that we create
Employee with Static public 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"); } }
Example: The Employee Objects 1000 Employee.nextEmpID public class Employee { private String name; private int empID; private static int nextEmpID = 1000; public Employee(String name) { this.name = name; emplID = nextEmpID; nextEmpID++; } … }
larry: Lawyer name = “Larry” empID = 1000; Example: The Employee Objects 1001 1000 Employee.nextEmpID public class Employee { private String name; private int empID; private static int nextEmpID = 1000; public Employee(String name) { this.name = name; emplID = nextEmpID; nextEmpID++; } … } Lawyer larry = new Lawyer("Larry");
larry: Lawyer mike: Marketer name = “Larry” empID = 1000; name = “Mike” empID = 1001; Example: The Employee Objects 1002 1001 Employee.nextEmpID public class Employee { private String name; private int empID; private static int nextEmpID = 1000; public Employee(String name) { this.name = name; emplID = nextEmpID; nextEmpID++; } … } Marketer mike = new Marketer("Mike");
Back to Hipster public 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 Critter[] critters = {new Ant(), newCougar(), 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
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 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 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 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; intcompareTo(Employee other) { return name.compareTo(other.name); }
Motivating Example: Sorting Persons 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 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 insertionSort Applies to any class X that has implemented the compareTo method
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.
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
Outline • Admin and recap • Interface • Motivation • Syntax
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."
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.
Interface Syntax • An interface is a collection of constants and abstract methods • abstract 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
interface is a reserved word A semicolon follows each method header immediately Interface: Example public interface Movable { public double getSpeed(); public void setSpeed(double speed); public void setDirection(int direction); public int getDirection(); } • This interface describes the behaviors common to all movable things.(Every Movable thing should have these methods.) No method in an interface has a definition (body)
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?)
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
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.)
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; } }
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 }
Outline • Admin and recap • Interface • Motivation • Syntax • Polymorphism through interface