Test 2 Flashcards
class declaration non static
As in the last lecture, the class declaration starts by specifying the class name public class Rectangle However, we also want to compare Rectangle objects (e.g., to sort them) public class Rectangle implements ComparableAdditional interfaces can be added in a comma-separated sequence
attributes non static
Remember that attributes are declared asaccess[static] [final] typename [= value]; We are choosing to declare private variables for the height and width, leaving them uninitializedprivate int width; private int height;
Static attributes are typically initialized when they are declared, non-static are initialized in the constructorAn attribute’s scope is the entire classThe fully qualified way to reference an attribute is with the thiskeywordthis.width or this.height However, thiscan be omitted if the result is unambiguous (e.g., attribute shadowing)
Constructors
are defined as follows: accessClassName(anyParameters)Like methods, they can be overloadedWhen a new object is created...◦Memory is allocated for the new object◦A constructor for the corresponding class is called ◦Attributes are initialized
Copy constructor
Takes an object of the same class as a parameter public ClassName(ClassName other)Creates a new object with attributes identical to the passed object Note that you do not need (and should not declare) a copy constructor for an immutable type, as the resulting object would be redundant
Constructor chaining
When a constructor invokes another constructor it is called constructor chainingTo invoke a constructor in the same class you use the thiskeyword◦If you do this then it must occur on the first line of the constructor bodyUsed to reduce code duplicationNot always feasible◦E.g., if constructor can throw exceptions
Methods
are defined as follows: access returnType signatureMethods can perform any operation on an object, but typically fall into categories: ◦Accessors – return an attribute value◦Mutators – modify an attribute value◦Obligatory – satisfy superclass or interface requirements◦Class-specific – defined by purpose of class
accessors
Allows access to (otherwise private) attribute valuesNaming convention:◦getX()for a non-Boolean attribute, named x◦isX()for a Boolean attribute, named xpublic int getWidth() { return this.width;} // similar for getHeight()
mutators
Allows modification of (otherwise private) attribute valuesNaming convention:
◦setX() for an attribute, named xpublic void setWidth(int width) { this.width = width; } // similar for setHeight()
validation using mutators
Instead of relying on preconditions, can use mutators to validate argument values
◦Throw an exception
◦Return a Boolean value For the Rectangle class, validate that any width argument is non-negative
validation with exceptions
/** Sets the width of this rectangle to the given width. @param width The new width of this rectangle.
@throws IllegalArgumentException
if width < 0.*/
public void setWidth(int width)
throws IllegalArgumentException{ if (width < 0) { throw new IllegalArgumentException(“Argument cannot be negative”); } else { this.width = width; } }
validation with boolean
/** Sets the width of this rectangle to the given width if the given width is greater than or equal to 0. Returns whether the width has been set. @param width The new width of this rectangle.@return true if width >= 0, false otherwise.*/ public boolean setWidth(int width){ boolean isSet = width >= 0; if (isSet) {this.width = width; } return isSet; }
toString method
Provides a textual representation of the Rectangle◦E.g., “Rectangle of width 1 and height 2”Default returns class name and memory addressFor the Rectangle class: public String toString() { return "Rectangle of width " + this.width + " and height " + this.height;}
equals method
Evaluate object equality using attribute values (i.e., object state) Default compares memory address (like ==)Implementing equals() is surprisingly hard ◦”One would expect that overriding equals(), since it is a fairly common task, should be a piece of cake. The reality is far from that. There is an amazing amount of disagreement in the Java community regarding correct implementation of equals().”Angelika Langer, Secrets of equals() – Part 1◦http://www.angelikalanger.com/Articles/JavaSolutions/SecretsOfEquals/Equals.htmlOur approach is consistent with many texts
instances of the same type
The implementation of equals() used in the notes and the textbook is based on the rule that an instance can only be equal to another instance of the same typeAt first glance, this sounds reasonable and is easy to implement using Object.getClass() public final Class extends Object> getClass() Returns the runtime class of an object.
instances with the same state are equal
Recall that the value of the attributes of an object define the state of the object Two instances are equal if all of their attributes are equal Recipe for checking equality of attributes1.If the attribute type is a primitive type other than float or double use ==2.If the attribute type is float use Float.compare()3.If the attribute type is double use Double.compare()4.If the attribute is an array consider Arrays.equals() 5.If the attribute is a reference type use equals(), but beware of attributes that might be null
equals()
For reference values equals() is
- Reflexive : An object is equal to itselfx.equals(x)is true
- Symmetric : Two objects must agree on whether they are equalx.equals(y)is trueif and only if y.equals(x)is true
- Transitive :If a first object is equal to a second, and the second object is equal to a third, then the first object must be equal to the thirdIf x.equals(y)is true, and y.equals(z)is true, then x.equals(z)must be true
- Consistent :Repeatedly comparing two objects yields the same result (assuming the state of the objects does not change)
- x.equals(null) is always false
compareTo()
Required if your class implements the Comparable interface (i.e., its object can be compared, order, or sorted)Compares this object with the specified object for order ◦Returns a negative integer if this object is less than ◦Returns a positive integer if this object is greater than ◦Returns zero if this object is equal to the passed oneThrows a ClassCastException if the specified object type cannot be compared to this object
comparable contract
1.The sign of the returned int must flip if the order of the two compared objects flip
if x.compareTo(y) > 0 then y.compareTo(x) < 0
if x.compareTo(y) < 0 then y.compareTo(x) > 0
if x.compareTo(y) == 0 then y.compareTo(x) == 0
2. compareTo()must be transitive
if x.compareTo(y) > 0 && y.compareTo(z) > 0 then x.compareTo(z) > 0
if x.compareTo(y) < 0 && y.compareTo(z) < 0 then x.compareTo(z) < 0
if x.compareTo(y) == 0 && y.compareTo(z) == 0then x.compareTo(z) == 0
3. If x.compareTo(y) == 0 then the signs of x.compareTo(z) and y.compareTo(z) must be the same
consistency with equals
An implementation of compareTo() is said to be consistent with equals() when if x.compareTo(y) == 0 then x.equals(y) == true and if x.equals(y) == true then x.compareTo(y) == 0
Implementing compareTo
is similar to implementing equalsTypically compare all of the attributes ◦Starting with the attribute that is most significant for ordering purposes and working your way downFor the Rectangle class, the API states that the width is used form comparison; if the widths are equal, the heights are used
hashCode
Hash codes used to uniquely (ideal) correspond to an object’s state (i.e., like a fingerprint or signature)Default uses memory address of the object Two objects with the same state should have the same hash code Hash-based containers use hash codes to organize and access elements efficiently
◦Performance increases with distinct hash codes
Poor, but legal implementation : public int hashCode() { return 1; } Better implementation : public int hashCode() { return this.getWidth() + this.getHeight(); }
Privacy leak
A mutable object that is passed to or returned from a method can be changed
Problems:
◦Private attributes become publicly accessible
◦Objects can be put into an inconsistent state
Solution: ◦Make a copy of the object and save the copyUse copy constructors
Bad
public void setDueDate(Date newDate){ dueDate = newDate; // Unsafe}
Good
public void setDueDate(Date newDate){ dueDate = new Date(newDate.getTime()); // Avoid leak }
immutable classes
A class defines an immutable type if an instance of the class cannot be modified after it is created Each instance has its own constant stateMore precisely, the externally visible state of each object appears to be constantJava examples: String, Integer (and all of the other primitive wrapper classes)Advantages of immutability versus mutabilityEasier to design, implement, and useCan never be put into an inconsistent state after creation
Recipe for Immutability
1.Do not provide any methods that can alter the state of the object Methods that modify state are called mutators
2.Prevent the class from being extended.Note that all classes extend java.lang.ObjectOne way to do this is to mark the class as final public final class PhoneNumber{ // version 0 } A final class cannot be extendedDon’t confuse final variable and final classes The reason for this step will become clear in a couple of weeks
3.Make all attributes final
Recall that Java will not allow a final attribute to be assigned to more than once
final attributes make your intent clear that the class is immutable public final class PhoneNumber{ // version 1 private final short areaCode; private final short exchange Code; private final short station Code; } Notice that the attributes are not initialized hereThat task belongs to the class constructors
4. Make all attributes privateThis applies to all public classes (including mutable classes)In public classes, strongly prefer private attributesAvoid using public attributesprivate attributes support encapsulationBecause they are not part of the API, you can change them (even remove them) without affecting any clientsThe class controls what happens to private attributesIt can prevent the attributes from being modified to an inconsistent state
5.Prevent clients from obtaining a reference to any mutable attributesRecall that final attributes have constant state only if the type of the attribute is a primitive or is immutableIf you allow a client to get a reference to a mutable attribute, the client can change the state of the attribute, and hence, the state of your immutable class