Classes, Objects, and Encapsulation
Transcription
Classes, Objects, and Encapsulation
Chapter outline Building Java Programs ! objects, classes, and object-oriented programming ! ! ! Chapter 3+5: Classes anatomy of a class ! ! ! ! ! ! ! ! fields instance methods constructors encapsulation advanced classes ! These are the slides of the textbook, modified/corrected where necessary. MIT Open Courseware has been utilized specifically for this chapter. relationship between classes and objects abstraction preconditions, postconditions, and invariants special methods: toString and equals the keyword this static fields and methods The chapters have been re-enumerated according to CMPE160. Copyright 2006 by Pearson Education 1 Copyright 2006 by Pearson Education Classes, types, and objects ! Objects and "OOP" class: ! 1. A module that can be run as a program. 2. A template for a type of objects. ! ! We can write Java classes that are not programs in themselves, but instead define new types of objects. ! ! object: An encapsulation of data and behavior. object-oriented programming (OOP): Writing programs that perform most of their useful behavior through interactions with objects. So far, we have interacted with objects such as: ! We can use these objects in our programs if we so desire. ! ! ! ! Why would we want to do this? ! ! ! ! ! Copyright 2006 by Pearson Education 2 3 String Point Scanner DrawingPanel Graphics Color Random File PrintStream Copyright 2006 by Pearson Education 4 Object Oriented Programming ! Object Oriented Programming OOP represents the real world. ! Objects group fields of different type together ! ! Let’s look at a real life example: ! ! ! Baby ! ! ! ! ! Name Sex Weight Decibels # poops so far 5 Copyright 2006 by Pearson Education Why use classes? ! Baby String name boolean isMale double weight double decibels int numPoops What kind of information should we keep about a baby? ! Primitives (int, double, char, etc.) Objects (String, etc.) Copyright 2006 by Pearson Education 6 Why use classes? Why not primitives? // little baby Alex String nameAlex; double weightAlex; //little baby David String nameDavid; double weightDavid; //little baby David String nameDavid2; double weightDavid2; David2 !!! What if there are 500 babies? Copyright 2006 by Pearson Education 7 Copyright 2006 by Pearson Education 8 Why use classes? Copyright 2006 by Pearson Education Why use classes? 9 Why use classes? Copyright 2006 by Pearson Education Copyright 2006 by Pearson Education 10 Why use classes? 11 Copyright 2006 by Pearson Education 12 Why use classes? DEFINING CLASSES Copyright 2006 by Pearson Education 13 Copyright 2006 by Pearson Education Class Definition Let’s write the Baby class Up to now, you have written Java programs composed of a single file (which also includes the main method). ! From now on, you will be writing programs composed of multiple files. ! ! Class names should be capitalized. Each class should be written in a separate file. ! Only one of the files should have the main method. ! ! 14 The class name and the file name should be the same. public class Baby { String name; boolean isMale; double weight; double decibels; int numPoops = 0; void poop() { numPoops ++; System.out.println(“Dear mother, ”+ “I have pooped. Ready the diaper.”); } } Copyright 2006 by Pearson Education 15 Copyright 2006 by Pearson Education 16 Let’s declare the Baby class Fields of the Baby class public class Baby { public class Baby { String name; double weight = 5.0; boolean isMale; int numPoops = 0; } } 17 Copyright 2006 by Pearson Education Siblings? Copyright 2006 by Pearson Education 18 Class vs. Variable vs. Object public class Baby { String name; double weight = 5.0; boolean isMale; int numPoops = 0; Baby myBaby; myBaby = new Baby(); OR Baby[] siblings; Baby myBaby = new Baby(); } Copyright 2006 by Pearson Education 19 Copyright 2006 by Pearson Education 20 Constructors Constructors Constructor name is the same as the class name. ! No return type. public class CLASSNAME { CLASSNAME ( ) { } ! ! ! It is not supposed to return anything. Executed as soon as the object is created. ! Not when a variable of that class type is defined. CLASSNAME ([ARGUMENTS]) { } Typically used to initialize the fields of the class. ! All classes need at least one constructor. ! ! } If you don’t provide any constructor the default constructor is assumed. CLASSNAME obj1 = new CLASSNAME(); CLASSNAME obj2 = new CLASSNAME([ARGUMENTS]); CLASSNAME() { } Copyright 2006 by Pearson Education 21 Copyright 2006 by Pearson Education Baby constructor 22 Baby methods public class Baby { String name; double weight = 5.0; boolean isMale; int numPoops = 0; Baby[] siblings; public class Baby { String name; boolean isMale; Baby(String myName, boolean maleBaby) { name = myName; isMale = maleBaby; } void sayHi() { System.out.println(“Hi, my name is ”+name); } void eat(double foodWeight) { if (foodWeight >= 0 && foodWeight < weight) { weight = weight + foodWeight; } } Baby(String myName, boolean maleBaby) { name = myName; isMale = maleBaby; } } } Copyright 2006 by Pearson Education 23 Copyright 2006 by Pearson Education 24 Classes and Instances // class Definition public class Baby {…} // class Instances Baby shiloh = new Baby(“Shiloh Jolie-Pitt”, true); Baby knox = new Baby(“Knox Jolie-Pitt”, true); USING CLASSES Copyright 2006 by Pearson Education 25 Copyright 2006 by Pearson Education Accessing fields and methods ! Recall: Point objects object.FIELDNAME ! Java has a class of objects named Point. ! ! Baby shiloh = new Baby(“Shiloh Jolie-Pitt”,true) System.out.println(shiloh.name); System.out.println(shiloh.numPoops); Point <name> = new Point(<x>, <y>); Point <name> = new Point(); // the origin, (0, 0) shiloh.sayHi(); shiloh.eat(1); ! Examples: Point p1 = new Point(5, -2); Point p2 = new Point(); Point objects are useful for several reasons: ! ! 27 To use Point, you must write: import java.awt.*; Constructing a Point object, general syntax: ! Copyright 2006 by Pearson Education 26 They store two values, an (x, y) pair, in a single variable. They have useful methods we can call in our programs. Copyright 2006 by Pearson Education 28 Recall: Point data/methods ! Data stored in each Point object: Field name ! A Point class ! ! Description x the point's x-coordinate y the point's y-coordinate A Point class might look something like this: ! Point class public Point() public Point(int x, int y) Useful methods of each Point object: Method name allows construction of Description distance(p) how far away the point is from point p setLocation(x, y) sets the point's x and y to the given values translate(dx, dy) adjusts the point's x and y by the given amounts ! Point object #1 Point objects can also be printed using println statements: Point p = new Point(5, -2); System.out.println(p); // java.awt.Point[x=5,y=-2] 29 Copyright 2006 by Pearson Education ! ! state: int x, y behavior: distance(Point p) equals(Point p) setLocation(int x, int y) toString() translate(int dx, int dy) behavior: distance(Point p) equals(Point p) setLocation(int x, int y) toString() translate(int dx, int dy) behavior: distance(Point p) equals(Point p) setLocation(int x, int y) toString() translate(int dx, int dy) Modifying a field, general syntax: <variable name> . <field name> = <value> ; // access // modify Later in this chapter, we'll learn about encapsulation, which will change the way we access the data inside objects. Copyright 2006 by Pearson Education client code: Code that uses an object. ! Examples: ! 30 Copyright 2006 by Pearson Education ! Accessing a field, general syntax: <variable name> . <field name> System.out.println("the x-coord is " + p1.x); p2.y = 13; Point object #3 state: int x, y Client code Code in other classes can access your object's fields. ! Point object #2 state: int x, y Accessing fields ! Each object contains its own data and methods. The class has the instructions for how to construct individual objects. 31 The client code below (PointMain.java) uses our Point class. public class PointMain { public static void main(String[] // create two Point objects Point p1 = new Point(); p1.x = 5; p1.y = 2; Point p2 = new Point(); p2.x = 4; p2.y = 3; // print each point System.out.println("p1 is (" System.out.println("p2 is (" // move p2 and then print it p2.x += 2; p2.y += 4; System.out.println("p2 is (" } } OUTPUT: p1 is (5, 2) p2 is (4, 3) p2 is (6, 7) Copyright 2006 by Pearson Education args) { + p1.x + ", " + p1.y + ")"); + p2.x + ", " + p2.y + ")"); again + p2.x + ", " + p2.y + ")"); 32 Client code question ! Client code redundancy Write a client program that uses our new Point class to produce the following output: p1 is (7, 2) p1's distance from origin = 7.280109889280518 p2 is (4, 3) p2's distance from origin = 5.0 p1 is (18, 8) p2 is (5, 10) ! ! Our client program had code such as the following to translate a Point object's location. // move p2 and then print it again p2.x += 2; p2.y += 4; System.out.println("p2 is (" + p2.x + ", " + p2.y + ")"); ! Recall that the formula to compute distance between two points (x1, y1) and (x2, y2) is: If we translate several points, the above code would be repeated several times in the client program. (x2 ! x1 )2 + ( y2 ! y1 )2 Copyright 2006 by Pearson Education 33 Copyright 2006 by Pearson Education Eliminating redundancy, v1 ! Classes with behavior We could eliminate the redundancy with a static method in the client for translating point coordinates: ! Why doesn't the method need to return the modified point? The static method solution isn't a good idea: ! ! ! The client would call the method as follows: When we wanted to use that behavior, we called a method of the object using the dot notation. // move p2 and then print it again p2.translate(2, 4); // move p2 and then print it again translate(p2, 2, 4); System.out.println("p2 is (" + p2.x + ", " + p2.y + ")"); System.out.println("p2 is (" + p2.x + ", " + p2.y + ")"); ! Copyright 2006 by Pearson Education The whole point of writing classes is to put related state and behavior together. This behavior is closely related to the x/y data of the Point object, so it belongs in the Point class. The objects we've used contain behavior inside them. ! ! The syntax doesn't match the way we're used to using objects. translate(p2, 2, 4); // Shifts the location of the given point. public static void translate(Point p, int dx, int dy) { p.x += dx; p.y += dy; } ! 34 35 In this section, we'll see how to add methods to our Point objects. Copyright 2006 by Pearson Education 36 Instance methods ! instance method: a method (without the static keyword) that defines the behavior for each object. ! ! Point object diagrams ! The object can refer to its own fields or methods as necessary. instance method declaration, general syntax: Point p2 = new Point(); p2.x = 4; p2.y = 3; x 7 public <type> <name> ( <parameter(s)> ) { <statement(s)> ; } ! Think of each Point object as having its own copy of the translate method, which operates on that object's state: Point p1 = new Point(); p1.x = 7; p1.y = 2; p1 Example (this code appears inside the Point class): public void translate(int dx, int dy) { ... } y 2 public void translate(int dx, int dy) { ... } x 4 y 3 public void translate(int dx, int dy) { ... } Copyright 2006 by Pearson Education p2 Copyright 2006 by Pearson Education 37 The implicit parameter ! Tracing instance method calls implicit parameter: The object on which an instance method is called. ! 38 ! What happens when the following calls are made? p1.translate(11, 6); Each instance method call happens on a particular object: p2.translate(1, 7); During the call p1.translate(11, 6); , the object referred to by p1 is the implicit parameter. ! During the call p2.translate(1, 7); , the object referred to by p2 is the implicit parameter. ! ! ! x p1 The instance method can refer to that object's fields. (We sometimes say that instance method code operates in the context of a particular object on each call.) x Copyright 2006 by Pearson Education p2 39 y 8 public void translate(int dx, int dy) { x += dx; y += dy; } Therefore the complete translate method should be: public void translate(int dx, int dy) { x += dx; y += dy; } 3 4 y 3 public void translate(int dx, int dy) { x += dx; y += dy; } Copyright 2006 by Pearson Education 40 Point class, version 2 ! Instance method questions This second version of Point gives a method named translate to each Point object: ! public class Point { int x; int y; Use the following formula: ! // Changes the location of this Point object. public void translate(int dx, int dy) { x += dx; y += dy; } ! } ! Each Point object now contains one method of behavior, which modifies its x and y coordinates by the given parameter values. 41 ! ! accessor: A method that provides access to information about an object. ! Generally the information comes from (or is computed using) the object's state stored in its fields. The distanceFromOrigin and distance methods are accessors. ! Sometimes the modification is based on parameters that are passed to the mutator method, such as the translate method with parameters for dx and dy. The translate and setLocation methods are mutators. Copyright 2006 by Pearson Education Modify the client code to use these new methods. 42 The following client code (stored in PointMain2.java) uses our modified Point class: public class PointMain2 { public static void main(String[] args) { // create two Point objects Point p1 = new Point(); p1.x = 5; p1.y = 2; Point p2 = new Point(); p2.x = 4; p2.y = 3; // print each point System.out.println("p1 is (" + p1.x + ", " + p1.y + ")"); System.out.println("p2 is (" + p2.x + ", " + p2.y + ")"); mutator: A method that modifies an object's state. ! You may wish to refactor your Point class to use this method. Client code, version 2 Two common categories of instance methods: ! Write an instance method named setLocation that accepts x and y values as parameters and changes the Point's location to be those values. Copyright 2006 by Pearson Education Accessors and mutators ! (x2 ! x1 )2 + ( y2 ! y1 )2 Write an instance method named distance that accepts a Point as a parameter and computes the distance between it and the current Point. ! ! Copyright 2006 by Pearson Education Write an instance method named distanceFromOrigin that computes and returns the distance between the current Point object and the origin, (0, 0). // move p2 and then print it again p2.translate(2, 4); System.out.println("p2 is (" + p2.x + ", " + p2.y + ")"); } } OUTPUT: p1 is (5, 2) p2 is (4, 3) p2 is (6, 7) 43 Copyright 2006 by Pearson Education 44 Client code question ! Recall our client program that produces this output: p1 is (7, 2) p1's distance from origin = 7.280109889280518 p2 is (4, 3) p2's distance from origin = 5.0 p1 is (18, 8) p2 is (5, 10) ! Modify the program to use our new instance methods. Also add the following output to the program: REFERENCES VS. VALUES distance from p1 to p2 = 3.1622776601683795 Copyright 2006 by Pearson Education 45 Copyright 2006 by Pearson Education Primitive types vs. References ! Primitive types are basic java types ! ! ! 46 How Java stores primitives Variables are like fixed size cups ! Primitives are small enough to fit into the cup ! int, long, double, boolean, char, short, byte, float The actual values are stored in the variable Reference types are arrays and objects ! String, int[], Baby, … Copyright 2006 by Pearson Education 47 Copyright 2006 by Pearson Education 48 How Java stores objects ! How Java stores objects Objects are too big to fit in a variable ! ! ! Stored somewhere else Variable stores a number that locates the object ! ! 49 Copyright 2006 by Pearson Education Objects are too big to fit in a variable References Stored somewhere else Variable stores a number (an address) that locates the object Copyright 2006 by Pearson Education 50 References The object’s location is called a reference ! == compares the references Baby shiloh1 = new Baby(“shiloh”); Baby shiloh2 = new Baby(“shiloh”); ! Baby shiloh1 = new Baby(“shiloh”); Baby shiloh2 = new Baby(“shiloh”); Does shiloh1 == shiloh2? NO ! Copyright 2006 by Pearson Education 51 Copyright 2006 by Pearson Education 52 References ! Object initialization: constructors Using = updates the reference. baby1 = baby2 reading: 8.4 53 Copyright 2006 by Pearson Education Copyright 2006 by Pearson Education Initializing objects ! Constructors It is tedious to have to construct an object and assign values to all of its data fields manually. Point p = new Point(); p.x = 3; p.y = 8; ! constructor: Initializes the state of new objects. ! ! // tedious ! ! We'd rather be able to pass in the fields' values as parameters, as we did with Java's built-in Point class. Point p = new Point(3, 8); ! Constructors may accept parameters to initialize the object. A constructor looks like a method, but it doesn't specify a return type, because it implicitly returns a new Point object. Constructor syntax: public <class name> ( <parameter(s)> ) { <statement(s)> ; } // better! ! To do this, we need to learn about a special type of method called a constructor. Copyright 2006 by Pearson Education 54 Example: public Point(int initialX, int initialY) { ... } 55 Copyright 2006 by Pearson Education 56 Point class, version 3 ! Tracing constructor calls This third version of the Point class provides a constructor to initialize Point objects: ! What happens when the following call is made? Point p1 = new Point(7, 2); public class Point { int x; int y; x public Point(int initialX, int initialY) { x = initialX; y = initialY; } p1 public void translate(int dx, int dy) { x += dx; y += dy; } } Copyright 2006 by Pearson Education public Point(int initialX, int initialY) { x = initialX; y = initialY; } public void translate(int dx, int dy) { x += dx; y += dy; } 57 58 Copyright 2006 by Pearson Education Client code, version 3 ! y Encapsulation The following client code (stored in PointMain3.java) uses our Point constructor: public class PointMain3 { public static void main(String[] args) { // create two Point objects Point p1 = new Point(5, 2); Point p2 = new Point(4, 3); reading: 8.5 // print each point System.out.println("p1 is (" + p1.x + ", " + p1.y + ")"); System.out.println("p2 is (" + p2.x + ", " + p2.y + ")"); } } // move p2 and then print it again p2.translate(2, 4); System.out.println("p2 is (" + p2.x + ", " + p2.y + ")"); OUTPUT: p1 is (5, 2) p2 is (4, 3) p2 is (6, 7) Copyright 2006 by Pearson Education 59 Copyright 2006 by Pearson Education 60 Encapsulation ! encapsulation: Hiding the implementation details of an object from the clients of the object. ! ! Implementing encapsulation ! (Protecting the object's fields from modification by clients.) Fields can be declared private to indicate that no code outside their own class can change them. ! Encapsulating objects provides abstraction; we can use them without knowing how they work. The object has: ! ! an external view (its behavior) an internal view (the state that accomplishes the behavior) ! ! Declaring a private field, general syntax: private <type> <name> ; Examples: private int x; private String name; Once fields are private, client code cannot directly access them. The client receives an error such as: PointMain.java:11: x has private access in Point System.out.println("p1 is (" + p1.x + ", " + p1.y + ")"); ^ Copyright 2006 by Pearson Education 61 Copyright 2006 by Pearson Education Encapsulation and accessors ! Benefits of encapsulation Once fields are private, we often provide accessor methods to examine their values: ! public int getX() { return x; } ! ! ! This gives clients "read-only" access to the object's fields. Encapsulation helps provide a clean layer of abstraction between an object and its clients. Encapsulation protects an object from unwanted access by clients. ! If so desired, we can also provide mutator methods: public void setX(int newX) { x = newX; } ! ! Question: Is there any difference between a public field and a private field with a get and set method? Copyright 2006 by Pearson Education 62 Encapsulation allows the class author to change the internal representation later if necessary. ! 63 For example, perhaps we write a program to manage users' bank accounts. We don't want a malicious client program to be able to arbitrarily change a BankAccount object's balance. For example, if so desired, the Point class could be rewritten to use polar coordinates (a radius r and an angle ! from the origin), but the external view could remain the same. Copyright 2006 by Pearson Education 64 Preconditions, postconditions, and invariants Point class, version 4 // A Point object represents an (x, y) location. public class Point { private int x; private int y; public Point(int initialX, int initialY) { x = initialX; y = initialY; } reading: 8.6 public double distanceFromOrigin() { return Math.sqrt(x * x + y * y); } public int getX() { return x; } public int getY() { return y; } public void setLocation(int newX, int newY) { x = newX; y = newY; } } public void translate(int dx, int dy) { x += dx; y += dy; } Copyright 2006 by Pearson Education 65 Copyright 2006 by Pearson Education Pre/postconditions Class invariants precondition: Something that you assume to be true when your method is called. ! postcondition: Something you promise to be true when your method exits. ! ! ! ! class invariant: An assertion about an object's state that is true throughout the lifetime of the object. ! Pre/postconditions are often documented as comments. ! Example: // Sets this Point's location to be the given (x, y). // Precondition: newX >= 0 && newY >= 0 // Postcondition: x >= 0 && y >= 0 public void setLocation(int newX, int newY) { x = newX; y = newY; } Copyright 2006 by Pearson Education 66 ! Example: "No BankAccount object's balance can be negative." Example: Suppose we want to ensure that all Point objects' x and y coordinates are never negative. ! ! 67 An invariant can be thought of as a postcondition on every constructor and mutator method of a class. We must ensure that a client cannot construct a Point object with a negative x or y value. We must ensure that a client cannot move an existing Point object to a negative (x, y) location. Copyright 2006 by Pearson Education 68 Violated preconditions ! Dealing with violations What if your precondition is not met? ! Sometimes the client passes an invalid value to your method. ! Example: ! ! Point pt = new Point(5, 17); Scanner console = new Scanner(System.in); System.out.print("Type the coordinates: "); int x = console.nextInt(); // what if the user types int y = console.nextInt(); // a negative number? pt.setLocation(x, y); ! ! ! One way to deal with this problem would be to return out of the method if negative values are encountered. How can we prevent the client from misusing our object? A more common solution is to have your object throw an exception. exception: A Java object that represents an error. ! ! Copyright 2006 by Pearson Education 69 Throwing exceptions example ! Copyright 2006 by Pearson Education 70 Encapsulation helps you enforce invariants. Throwing an exception, general syntax: ! Example: // Sets this Point's location to be the given (x, y). // Throws an exception if newX or newY is negative. // Postcondition: x >= 0 && y >= 0 public void setLocation(int newX, int newY) { if (newX < 0 || newY < 0) { throw new IllegalArgumentException(); } x = newX; y = newY; } Copyright 2006 by Pearson Education When a precondition of your method has been violated, you can generate ("throw") an exception in your code. This will cause the client program to halt. (That'll show 'em!) Encapsulation and invariants throw new <exception type> (); or throw new <exception type> ("<message>"); ! The <message> will be shown on the console when the program crashes. ! However, it is not possible to do something similar in the constructor, and the client doesn't expect this behavior. ! ! 71 Ensure that no Point is constructed with negative x or y: public Point(int initialX, int initialY) { if (initialX < 0 || initialY < 0) { throw new IllegalArgumentException(); } x = initialX; y = initialY; } Ensure that no Point can be moved to a negative x or y: public void translate(int dx, int dy) { if (x + dx < 0 || y + dy < 0) { throw new IllegalArgumentException(); } x += dx; y += dy; } Other methods require similar modifications. Copyright 2006 by Pearson Education 72 Special instance methods: toString, equals Problem: object printability ! By default, Java doesn't know how to print the state of your objects, so it prints a strange result: Point p = new Point(10, 7); System.out.println("p is " + p); reading: 8.6 ! // p is Point@9e8c34 We can instead print a more complex string that shows the object's state, but this is cumbersome. System.out.println("(" + p.x + ", " + p.y + ")"); ! We'd like to be able to print the object itself and have something meaningful appear. // desired behavior: System.out.println("p is " + p); Copyright 2006 by Pearson Education 73 Copyright 2006 by Pearson Education The toString method ! ! ! ! The toString method is called when your object is printed or concatenated with a String. Point p1 = new Point(7, 2); System.out.println("p1 is " + p1); ! If you prefer, you can write the .toString() explicitly. System.out.println("p1 is " + p1.toString()); The default toString behavior is to return the class's name followed by a hexadecimal (base-16) number: Example: The Point class in java.awt has a toString method that converts a Point into a String such as: "java.awt.Point [x=7,y=2]" The toString method, general syntax: ! ! public String toString() { <statement(s) that return an appropriate String> ; } The method must have this exact name and signature. Example: // Returns a String representing this Point. public String toString() { return "(" + x + ", " + y + ")"; } Point@9e8c34 Copyright 2006 by Pearson Education You can replace the default behavior by defining an appropriate toString method in your class. ! Every class contains a toString method, even if it isn't written in your class's code. ! 74 toString method syntax The special method toString tells Java how to convert your object into a String as needed. ! // p is (10, 7) 75 Copyright 2006 by Pearson Education 76 Recall: comparing objects ! The equals method The == operator does not work well with objects. ! == compares references to objects and only evaluates to true if two variables refer to the same object. ! ! ! ! It doesn't tell us whether two objects have the same state. ! Example: Point p1 = new Point(5, 3); Point p2 = new Point(5, 3); if (p1 == p2) { // false System.out.println("equal"); } p1 p2 x 5 y ! 3 We can replace this default behavior by writing an equals method. ! 5 y When we write our own new classes of objects, Java doesn't know how to compare their state. The default equals behavior acts just like the == operator. if (p1.equals(p2)) { // still false System.out.println("equal"); } ... x The equals method compares the state of objects. The method will actually compare the state of the two objects and return true for cases like the above. 3 ... Copyright 2006 by Pearson Education 77 Copyright 2006 by Pearson Education Initial flawed equals method ! ! equals and the Object class You might think that the following is a valid implementation of the equals method: ! ! equals should not accept a parameter of type Point. ! public boolean equals(Point other) { if (x == other.x && y == other.y) { return true; } else { return false; } } However, it has several flaws that we should correct. It should be legal to compare Points to any other object, e.g.: Point p = new Point(7, 2); if (p.equals("hello")) { // false ... } ! One initial flaw: the body can be shortened to: The equals method, general syntax: ! return x == other.x && y == other.y; Copyright 2006 by Pearson Education 78 79 public boolean equals(Object <name>) { <statement(s) that return a boolean value> ; } The parameter to a proper equals method must be of type Object (meaning that an object of any type can be passed). Copyright 2006 by Pearson Education 80 Another flawed version ! Type-casting objects You might think that the following is a valid implementation of the equals method: ! public boolean equals(Object o) { if (x == o.x && y == o.y) { return true; } else { return false; } } ! The object that is passed to equals can be cast from Object into your class's type. ! public boolean equals(Object o) { Point other = (Point) o; return x == other.x && y == other.y; } ! However, it does not compile. Point.java:36: cannot find symbol symbol : variable x location: class java.lang.Object if (x == o.x && y == o.y) { ^ Type-casting with objects behaves differently than casting primitive values. ! ! 81 Copyright 2006 by Pearson Education ! Point p1 = new Point(5, 3); Point p2 = new Point(5, 3); if (p1.equals(p2)) { System.out.println("equal"); } 5 y p2 Our equals code still is not complete. ! 3 ! o p1 public boolean equals(Object o) { other Point other = (Point) o; return x == other.x && y == other.y; } x 5 y ! 3 ... Copyright 2006 by Pearson Education 82 Comparing different types Client code: x We are really casting a reference of type Object into a reference of type Point. We're promising the compiler that o refers to a Point object. Copyright 2006 by Pearson Education Casting objects diagram ! Example: 83 When we compare Point objects to any other type of objects, Point p = new Point(7, 2); if (p.equals("hello")) { // false ... } Currently the code crashes with the following exception: Exception in thread "main" java.lang.ClassCastException: java.lang.String at Point.equals(Point.java:25) at PointMain.main(PointMain.java:25) The culprit is the following line that contains the type-cast: public boolean equals(Object o) { Point other = (Point) o; Copyright 2006 by Pearson Education 84 The instanceof keyword ! Final version of equals method We can use a keyword called instanceof to ask whether a variable refers to an object of a given type. ! ! ! ! The instanceof keyword, general syntax: <variable> instanceof <type> // Returns whether o refers to a Point object with // the same (x, y) coordinates as this Point object. public boolean equals(Object o) { if (o instanceof Point) { Point other = (Point) o; return x == other.x && y == other.y; } else { return false; } } The above is a boolean expression that can be used as the test in an if statement. Examples: String s = "hello"; Point p = new Point(); expression result s instanceof Point false s instanceof String true p instanceof Point true p instanceof String false This version of the equals method allows us to correctly compare Point objects against any other type of object: null instanceof String false 85 Copyright 2006 by Pearson Education Copyright 2006 by Pearson Education Using the keyword this The keyword this ! this : A reference to the implicit parameter. ! reading: 8.7 ! ! ! 87 Recall: The implicit parameter is the object on which an instance method or constructor is being called. Usage of the this keyword, general syntax: ! Copyright 2006 by Pearson Education 86 To refer to a field: this.<field name> To refer to a method: this.<method name>(<parameters>); To call a constructor from another constructor: this(<parameters>); Copyright 2006 by Pearson Education 88 Variable shadowing ! Avoiding shadowing with this shadowed variable: A field that is "covered up" by a local variable or parameter with the same name. ! ! ! Normally it is illegal to have two variables in the same scope with the same name, but in this case it is allowed. public void setLocation(int x, int y) { if (x < 0 || y < 0) { throw new IllegalArgumentException(); } this.x = x; this.y = y; } To avoid shadowing, we named our setLocation parameters newX and newY: public void setLocation(int newX, int newY) { if (newX < 0 || newY < 0) { throw new IllegalArgumentException(); } x = newX; y = newY; } Copyright 2006 by Pearson Education ! ! 89 ! The constructors must accept different parameters. One constructor can call another using this . ! public class Point { private int x; private int y; We can also use the this. field syntax so that the constructor parameters' names can match the field names. public class Point { private int x; private int y; public Point() { x = 0; y = 0; } public Point() { this(0, 0); } public Point(int initialX, int initialY) { x = initialX; y = initialY; } } // calls the (x, y) constructor public Point(int x, int y) { this.x = x; this.y = y; } ... Copyright 2006 by Pearson Education 90 Multiple constructors w/ this It is legal to have more than one constructor in a class. ! When this. is not seen, the parameter is used. When this. is seen, the field is used. Copyright 2006 by Pearson Education Multiple constructors ! The this keyword lets us use the same names and still avoid shadowing: } 91 ... Copyright 2006 by Pearson Education 92 Object practice problem More class problems ! Create a class named Circle. ! ! ! ! ! Copyright 2006 by Pearson Education 93 ! A line segment is represented by two endpoints (x1, y1) and (x2, y2). Create a class named Calculator. ! ! ! ! ! ! A line segment should be able to compute its slope (y2-y1) / (x2-x1). A line segment should be able to tell whether a given point intersects it. Line segments should be able to draw themselves using a Graphics object. Line segments should be able to be printed on the console, and should be able to be compared to other lines for equality. Copyright 2006 by Pearson Education 94 Object practice problem Create a class named LineSegment. ! Circles should be able to tell whether a given point is contained inside them. Circles should be able to draw themselves using Graphics. Circles should be able to be printed on the console, and should be able to be compared to other circles for equality. Copyright 2006 by Pearson Education Object practice problem ! A circle is represented by a point for its center, and its radius. Make it possible to construct the unit circle, centered at (0, 0) with radius 1, by passing no parameters to the constructor. 95 ! A calculator has a method to add digits to a running total. The user can also press operator keys such as + or * and then enter digits of a second number. When the user presses the = button, the calculator computes the result based on the numbers entered so far and the operator chosen. The user can then make further computations. Copyright 2006 by Pearson Education 96 Calculator client code ! Use your Calculator with a client such as the following: public class CalculatorMain { public static void main(String[] args) { Calculator calc = new Calculator(); // first computation: calculate 329 + 1748 = 2077 calc.addDigit(3); calc.addDigit(2); calc.addDigit(9); calc.setOperator("+"); calc.addDigit(1); calc.addDigit(7); calc.addDigit(4); calc.addDigit(8); STATIC TYPES & METHODS int result = calc.compute(); } } System.out.println(calc); System.out.println("result = " + result); 97 Copyright 2006 by Pearson Education Copyright 2006 by Pearson Education static Keeping a global counter Applies to fields and methods ! Means the field /method is: Keep track of the number of babies that have been made. public class Baby { int numBabiesMade = 0; Baby() { numBabiesMade++; } } ! ! ! ! 98 defined for the class declaration not unique for each instance Baby b1 = new Baby(); Baby b2 = new Baby() ! What is b1.numBabiesMade? b2.numBabiesMade? Copyright 2006 by Pearson Education 99 Copyright 2006 by Pearson Education 100 Keeping a global counter static method public class Baby { static int numBabiesMade = 0; Baby() { numBabiesMade++; } } Copyright 2006 by Pearson Education public class Baby { static void cry(Baby thebaby) { System.out.println(thebaby.name + “cries”); } } 101 Copyright 2006 by Pearson Education Use of static Use of static When a number of objects are created from the same class, each instance has its own copy of class variables. But this is not the case when it is declared as static static. ! A static method or a static variable is not attached to a particular object, but rather to the class as a whole. ! A static variable is a variable who's single copy in memory is shared by all objects, so any modifications to the static variable will modify it's value in all objects. ! Copyright 2006 by Pearson Education 102 103 ! Static methods cannot access instance variables. ! ! Static methods can be referenced with the name of the particular class, not the object. ! ! They can access local variables and parameters. That's how the library methods like System.out.println, Math.sqrt work. !"#$%&'()*+,&-".%*)'#*/,0,/,#),*%&'()*+,&-".%1*23&*#"&*&-,*"&-,/* 4'5*'/"3#.6 Copyright 2006 by Pearson Education 104