Methods Common to all Classes 9-2-2013
OOP concepts Overloading vs. Overriding Use of this. and this(); use of super. and super() Methods common to all classes: tostring(), equals(), hashcode() HW#1 posted; due Wednesday, 9/4/13 Reading Assignment: Effective Java 2 (EJ2) Chapter 3 Methods Common to All Objects, Items 8-10
public class Circle { private float radius; private Point center; A Circle has a Point UML Class Diagram Circle FilledCircle HAS-A (composition) 1 Point
Object UML Class Diagram IS-A (inheritance) A Circle is an Object Circle public class Circle { /* stuff */ (everything is an Object, except for a primitive value)
public class Circle { private float radius; private Point center; public Circle(int x, int y) public Circle(float r,int x,int y) public float getradius() public float computearea() // end class Circle IS-A Circle FilledCircle public class FilledCircle extends Circle { private Color fillcolor; public FilledCircle(float r, int x,int y, Color acolor) public float getcolor() // end class FilledCircle
Object IS-A IS-A Circle HAS-A (composition) 1 Point IS-A (inheritance) FilledCircle
Object methods: getclass(), tostring(), equals(), hashcode(), etc. Circle methods: constructors, get/setcenter(), get/setradius(), computearea() FilledCircle methods: constructors, get/setcolor()
Overloading multiple versions of a method, distinguished by their signatures (name and argument list) Overriding when a subclass completely replaces a method that it inherits from its superclass (same signature)
multiple versions of a method, distinguished by their signatures (name & argument list) it is very common to overload constructors example: public Circle(int x, int y) // creates unit circle public Circle(float radius, int x, inty)
can override an inherited method completely (that is, replace it) can specialize an inherited method by overriding the method in the superclass, but reusing code from the superclass It s common to do both
this reference to current object this.radius this() way to call another constructor in the same class
public Circle(float radius, int x, int y) { this.radius = radius; this.center = new Point(x,y); public Circle(int x, int y) { this(1.0f, x, y); /* reuses code */ advantage: can change the implementation without changing all the other constructors
public Circle(int x, int y) { this.radius = 1.0f; this.center = new Point(x,y); public Circle(float radius, int x, int y) { this(x, y); this.radius = radius;
this. see a dot => reference to the current object this( see opening parenthesis => calling another constructor in the same class
FilledCircle fc1 = new FilledCircle(1.5f, 100, 200, Color.blue); fc1 FilledCircle FilledCircle Circle center radius 1.5 fillcolor blue Point x y 100 200
public class Circle { private float radius; private Point center; public Circle(float r,int x,int y) { radius = r; center = new Point(x,y); public Circle(int x, int y) { this(1.0f, x, y); public float getradius() public float computearea() // end class Circle IS-A Circle FilledCircle public class FilledCircle extends Circle { private Color fillcolor; public FilledCircle(float r, int x, int y, Color acolor) { super(r, x, y); fillcolor = acolor; public float getcolor() // end class FilledCircle
super. see a dot => reference to a field or method in the embedded superclass super( see opening parenthesis => calling a superclass constructor
cf. Effective Java, Chapter 3 superclass java.lang.object methods: tostring(), equals(), hashcode(), finalize(), clone(), getclass(), wait(), notify(), notifyall() Which of these typically need to be specialized in subclasses? tostring(), equals(), hashcode() What about comparing objects? compareto()
System.out.println( Answer = + 42 ); String int in this context, + means String concatenation (polymorphic) So the int value 42 is converted to a string with the method Integer.toString()
Consider the following code: Circle c1 = new Circle(1.5f, 25, 80); System.out.println (c1); What gets printed? Why? Problem: c1.tostring() is automatically called. Search the inheritance hierarchy for a method tostring(), starting at Circle. Find and invoke the method in Object. Prints Circle@1be2d65 Solution: override tostring()
Object methods: getclass(), tostring(), equals(), getclass(), etc. Circle methods: constructors, get/setcenter(), get/setradius(), computearea() tostring(), equals(), hashcode() FilledCircle methods: constructors, get/setcolor() tostring(), equals(), hashcode()
cf. Effective Java 2, pp. 51-53 tostring returns a meaningful description of the object Can specify a format example: phone numbers, p. 52
public class Circle { // other stuff public String tostring() { return (this.getclass() + \n\t Center + this.center + \n\t Radius = + this.radius ); // note: Point should also override tostring()
public class Circle { // other stuff @Override public String tostring() { return (this.getclass() + \n\t Center + this.center + \n\t Radius = + this.radius ); // note: Point should also override tostring()
public class FilledCircle { // other stuff @Override public String tostring() { return (super.tostring() + \n\t Color + this.fillcolor() );
Just about every class needs its own tostring() method, but not every class needs its own equals() method that tests for equal values example: Random equals() doesn t apply the equals() inherited from your superclass already tests what you want the class is private (or package-private) and you are certain that equals() will never be invoked; in that case, an accidental call to equals() should be an error (more on exceptions later)
Override Object.equals() when objects in your class can be equal in value in some sense, different from equivalent circles, lines, dice? other? value classes Bloch, Effective Java 2, p. 34
flawed public class Circle { equals() must return boolean doesn t override Object.equals() the argument must be Object public Boolean equals(circle o) { return (this.radius == o.radius) && (this.center == o.center) ; to override a method, must have the same signature & return type
public class Circle { public boolean equals(object o) { return (this.radius == o.radius) && (this.center == o.center) ; flawed radius & center are private, it s OK here, but may need accessor functions to avoid breaking encapsulation of other classes center is a Point; can t test for equality w/ ==
public class Circle { public boolean equals(object o) { return ( this.radius == o.radius ) && ( (this.center).equals(o.center) ); flawed what if o is null? get a NullPointerException what if object o refers to something other than a circle, like a die for instance?
reflexive x.equals(x) is true symmetric x.equals(y) iff y.equals(x) transitive x.equals(y) && y.equals(z) => x.equals(z) consistent multiple calls to x.equals(y) all give the same result cautious x.equals(null) is false
public class Circle { public boolean equals(object o) { if (o == null) return false; if (o == this) return true; if (!(o instanceof Circle)) return false; Circle other = (Circle) o; /* required, but will be detected by the instanceof operator anyway */ /* not strictly required, but efficient */ /* this cast cannot fail */ return (this.radius == other.radius) && (this.center).equals(other.center) );
public boolean equals(object o) { if (this == o) return true; if (!(o instanceof Circle)) return false; Circle other = (Circle) o; /* include this performance optimization when the equals test is complex */ return (this.radius == other.radius) && ( (this.center).equals(other.center) ); /* cf. Effective Java pp. 33-34 for float, double, array */
Suppose you are the class designer for a new class T T has 3 fields: field1, field2, field3 of types A, B and C respectively (can generalize to n fields). A field1 suppose that A is a primitive type (like int) B field2 suppose that you will ignore this when testing for equality C field3 suppose that C is an object
public boolean equals(object o) { /* compares fields 1 and 3 for equality */ if (!(o instanceof T)) return false; T other = (T) o; return ( (this.field1 == other.field1) && (this.field3).equals(other.field3) );