230 likes | 238 Views
Building Java Programs. Chapter 8: Classes Lecture 8-3: More Critters, static. Encapsulation. encapsulation : Hiding implementation details of an object from its clients. Encapsulation provides abstraction . separates external view (behavior) from internal view (state)
E N D
Building Java Programs Chapter 8: Classes Lecture 8-3: More Critters, static
Encapsulation • encapsulation: Hiding implementation details of an object from its clients. • Encapsulation provides abstraction. • separates external view (behavior) from internal view (state) • Encapsulation protects the integrity of an object's data.
Private fields • A field can be declared private. • No code outside the class can access or change it. privatetypename; • Examples: private int id; private String name; • Client code sees an error when accessing private fields: PointMain.java:11: x has private access in Point System.out.println("p1 is (" + p1.x + ", " + p1.y + ")"); ^
Benefits of encapsulation • Provides abstraction between an object and its clients. • Protects an object from unwanted access by clients. • A bank app forbids a client to change an Account's balance. • Allows you to change the class implementation. • Point could be rewritten to use polar coordinates(radius r, angle θ), but with the same methods. • Allows you to constrain objects' state (invariants). • Example: A Hero’s hitPoints never goes below 0.
How the simulator works • When you press "Go", the simulator enters a loop: • move each animal once (getMove), in random order • if the animal has moved onto an occupied square, fight! • if the animal has moved onto food, ask it if it wants to eat • Key concept: The simulator is in control, NOT your animal. • Example: getMove can return only one move at a time.getMove can't use loops to return a sequence of moves. • Your animal must keep state (as fields) so that it can make a single move, and know what moves to make later.
Ideas for state • You must not only have the right state, but update that state properly when relevant actions occur. • Counting is helpful: • How many total moves has this animal made? • How many times has it eaten? Fought? • Remembering recent actions in fields is 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 Critter type • 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"
Determining necessary fields • Information required to decide what move to make? • Direction to go in • Length of current cycle • Number of moves made in current cycle • Information required to decide how to fight? • A Random object
Snake solution import java.awt.*; // for Color import java.util.*; // for Random public class Snake extends Critter { private int length; // # steps in current horizontal cycle private int step; // # of cycle's steps already taken private Random rand; // for fighting public Snake() { length = 1; step = 0; rand = new Random(); } public Direction getMove() { step++; if (step > length) { // cycle was just completed length++; step = 0; return Direction.SOUTH; } else if (length % 2 == 1) { return Direction.EAST; } else { return Direction.WEST; } } ...
Snake solution 2 ... public Attack fight(String opponent) { int attack = rand.nextInt(2); if (attack == 0) { return Attack.POUNCE; } else { return Attack.ROAR; } } public String toString() { return "S"; } public Color getColor() { return new Color(20, 50, 128); } // We don't need to write an eat method; // We can just keep the default eat behavior (returning false) }
Critter: Drunken Frat Guy • All DFG Critters are trying to get to the same party • The party is at a randomly-generated location • On a 60px wide by 50px tall world • They stumble north then east until they reach the party
DFG: a flawed solution import java.util.*; public class DrunkenFratGuy extends Critter { private int partyX; private int partyY; public DrunkenFratGuy() { Random r = new Random(); partyX = r.nextInt(60); partyY = r.nextInt(50); } public Direction getMove() { if(partyY != getY()) { return Direction.NORTH; } else if(partyX != getX()) { return Direction.EAST; } else { return Direction.CENTER; } } }
DFG: Where did they all go? • Each DFG is heading to its own party! • We need a way for Critters of a type to share information • Tournament-winning Huskies do this • Hunt in packs • Don't kill each other • Share location of opponents
Static fields vs. fields • static: Part of a class, rather than part of an object. • A single static field is shared by all objects of that class • static field, general syntax: private static typename; or, private static typename = value; • Example: private static int count = 0;
Static field example • Count the number of Husky objects created: public class Husky implements Critter { // count of Huskies created so far private static int objectCount = 0; private int number; // each Husky has a number public Husky() { objectCount++; number = objectCount; } ... public String toString() { return "I am Husky #" + number + "out of " + objectCount; } }
Static methods • static method: part of a class, not part of an object. • shared by all objects of that class • does not understand the implicit parameter; therefore, cannot access fields directly • if public, can be called from inside or outside the class • Declaration syntax: (same as we have seen before) public static return typename(params) { statements; } • Methods that do not access/modify the object’s state should be made static
Static method example 1 • Java's built-in Math class has code that looks like this: public class Math { ... public static int abs(int a) { if (a >= 0) { return a; } else { return -a; } } public static int max(int a, int b) { if (a >= b) { return a; } else { return b; } } }
Calling static methods, outside • Static method call syntax (outside the class): class name.method name(values); • This is the syntax client code uses to call a static method. • Examples: int absVal = Math.max(5, 7); double[] a1 = {2.4, 2.5, 60.3, -4.1}; double[] a2 = Arrays.copyOf(a1, a1.length);
Calling static methods, inside • Static method call syntax (inside the class): method name(values); • This is the syntax the class uses to call its own static method. • Example: public class Math { // other methods such as ceil, floor, abs, etc. // ... public static int round(double d) { if (d - (int) d >= 0.5) { return ceil(d); } else { return floor(d); } } }
DFG: all go to the same party import java.util.*; public class DrunkenFratGuy extends Critter { private static int partyX; private static int partyY; public DrunkenFratGuy() { Random r = new Random(); partyX = r.nextInt(60); partyY = r.nextInt(50); } public Direction getMove() { if(partyY != getY()) { return Direction.NORTH; } else if(partyX != getX()) { return Direction.EAST; } else { return Direction.CENTER; } } }