Identity and Equality Based on material by Michael Ernst, University of Washington.

Slides:



Advertisements
Similar presentations
More on Classes Inheritance and Polymorphism
Advertisements

 Specifies a set of methods (i.e., method headings) that any class that implements that interface must have.  An interface is a type (but is not a class).
Chapter 1 Object-Oriented Concepts. A class consists of variables called fields together with functions called methods that act on those fields.
SUMMARY: abstract classes and interfaces 1 Make a class abstract so instances of it cannot be created. Make a method abstract so it must be overridden.
Java Review Interface, Casting, Generics, Iterator.
Reasoning About Code; Hoare Logic, continued
METHOD OVERRIDING 1.Sub class can override the methods defined by the super class. 2.Overridden Methods in the sub classes should have same name, same.
Singleton vs utility class  at first glance, the singleton pattern does not seem to offer any advantages to using a utility class  i.e., a utility class.
Composition CMSC 202. Code Reuse Effective software development relies on reusing existing code. Code reuse must be more than just copying code and changing.
Effective Java, Chapter 3: Methods Common to All Objects.
Slides 4/22 COP Topics Final Exam Review Final Exam The final exam is Friday, April 29 th at 10:00 AM in the usual room No notes, books, calculators,
C8: Understanding Inheritance. Intuitive description Intuitive: FLORISTS are SHOPKEEPERS, inheriting various shopkeeper behaviors Tension in OOP languages:
== equals ? CSE 331 SOFTWARE DESIGN & IMPLEMENTATION EQUALITY Autumn 2011.
Overview of Java (continue). Announcements You should have access to your repositories and HW0 If you have problems getting HW0, let me know If you’ve.
CS2200 Software Development Lecture: Object class A. O’Riordan, 2008.
Interfaces. In this class, we will cover: What an interface is Why you would use an interface Creating an interface Using an interface Cloning an object.
1 Java Object Model Part 2: the Object class. 2 Object class Superclass for all Java classes Any class without explicit extends clause is a direct subclass.
Polymorphism. Lecture Objectives To understand the concept of polymorphism To understand the concept of static or early binding To understand the concept.
Inheritance Part II. Lecture Objectives To learn about inheritance To understand how to inherit and override superclass methods To be able to invoke superclass.
Procedure specifications CSE 331. Outline Satisfying a specification; substitutability Stronger and weaker specifications - Comparing by hand - Comparing.
1 Inheritance and Polymorphism Chapter 9. 2 Polymorphism, Dynamic Binding and Generic Programming public class Test { public static void main(String[]
CISC6795: Spring Object-Oriented Programming: Polymorphism.
Equality CSE 331 University of Washington. Object equality A simple idea - we have intuitions about equality: - Two objects are equal if they have the.
1 Object-Oriented Software Engineering CS Interfaces Interfaces are contracts Contracts between software groups Defines how software interacts with.
Programming in Java Unit 2. Class and variable declaration A class is best thought of as a template from which objects are created. You can create many.
Puzzle 3 1  Write the class Enigma, which extends Object, so that the following program prints false: public class Conundrum { public static void main(String[]
Non-static classes Part 2 1. Methods  like constructors, all non-static methods have an implicit parameter named this  for methods, this refers to the.
Effective C#, Chapter 1: C# Language Elements Last Updated: Fall 2011.
Design Patterns Gang Qian Department of Computer Science University of Central Oklahoma.
Chapter 3 Inheritance and Polymorphism Goals: 1.Superclasses and subclasses 2.Inheritance Hierarchy 3.Polymorphism 4.Type Compatibility 5.Abstract Classes.
CSE 331 Software Design & Implementation Hal Perkins Winter 2013 ==, equals(), and all that (Slides by David Notkin and Mike Ernst) 1.
Types in programming languages1 What are types, and why do we need them?
Fall 2010 UVa David Evans cs2220: Engineering Software Class 27: Exam 2.
Type Abstraction SWE Spring October 05Kaushik, Ammann Substitution Principle “In any client code, if supertype object is substituted.
Inheritance (Part 5) Odds and ends 1. Static Methods and Inheritance  there is a significant difference between calling a static method and calling a.
Object Oriented Programming
Subtype Polymorphism, Subtyping vs
Parametric Polymorphism and Java Generics. Announcements One day extension on HW5 Because of an error in my HW5 config HW6 out, due November 10 Grades.
Chapter 8 Class Inheritance and Interfaces F Superclasses and Subclasses  Keywords: super F Overriding methods  The Object Class  Modifiers: protected,
Inheritance Type/Subtype Relationship. Inheritance Idea: An object B of one type, termed child class, inherits from another object A of another type,
Chapter 11: Advanced Inheritance Concepts. Objectives Create and use abstract classes Use dynamic method binding Create arrays of subclass objects Use.
CSI 3125, Preliminaries, page 1 Inheritance. CSI 3125, Preliminaries, page 2 Inheritance Using inheritance, can create a general class that defines traits.
1 Object-Oriented Programming Inheritance. 2 Superclasses and Subclasses Superclasses and Subclasses  Superclasses and subclasses Object of one class.
Inheritance and Polymorphism
Terms and Rules II Professor Evan Korth New York University (All rights reserved)
Reference Types CSE301 University of Sunderland Harry R Erwin, PhD.
Subtype Polymorphism, Subtyping vs. Subclassing, Liskov Substitution Principle.
Reasoning and Design (and Assertions). How to Design Your Code The hard way: Just start coding. When something doesn’t work, code some more! The easier.
Notices Assn 2 is due tomorrow, 7pm. Moodle quiz next week – written in the lab as before. Everything up to and including today’s lecture: Big Topics are.
Testing (final thoughts). equals() and hashCode() Important when using Hash-based containers class Duration { public final int min; public final int sec;
1 clone() Defined in Object Creates an identical copy –Copies pointers to fields (does not copy fields of fields) –Makes a shallow copy if the object’s.
9.1 CLASS (STATIC) VARIABLES AND METHODS Defining classes is only one aspect of object-oriented programming. The real power of object-oriented programming.
Modern Programming Tools And Techniques-I
Inheritance and Polymorphism
Subtype Polymorphism, Subtyping vs
Computer Science II Exam 1 Review.
CSE 331 Software Design and Implementation
Testing, conclusion Based on material by Michael Ernst, University of Washington.
Testing, cont., Equality and Identity
Specifications, conclusion. Abstract Data Types (ADTs)
Equality, conclusion Based on material by Michael Ernst, University of Washington.
Subtype Polymorphism, Subtyping vs
CSE 143 Lecture 24 Inheritance and the Object class; Polymorphism
CSE 143 Lecture 24 Inheritance and the Object class; Polymorphism
CSE 143 Lecture 24 Inheritance and the Object class; Polymorphism
CSE 143 Lecture 23 Inheritance and the Object class; Polymorphism
CMPE212 – Reminders Assignment 2 due next Friday.
Review for Midterm 3.
CS 240 – Advanced Programming Concepts
Presentation transcript:

Identity and Equality Based on material by Michael Ernst, University of Washington

Announcements HW4 due March 31st Several tasks 1) design the ADT following the ADT methodology Mutable vs. immutable Operations (creators, mutators, etc.) + their specs 2) specification tests (before coding, test-first principle) 3) then write code 4) then write implementation tests, measure coverage Grades HW 0-3, Exam1, Quiz 1-3 are in LMS. Will add Quiz 4 after class

From Quiz 4: Catching Exceptions by Subsumption IndexOutOfBoundsException is a subclass of RuntimeException. Therefore, the catch block catches and handles the exception. void m() { try { String s = new String(“car”); String sub = s.substring(5); // throws IndexOutOfBoundsExcetpion } catch (RuntimeException e) { e.printStackTrace(); System.out.println(“continues with m”); Spring 15 CSCI 2600, A Milanova

Last Class, Concluded Testing Testing is a major part of quality assurance (QA) QA includes other activities: Dynamic analysis (monitor program execution) E.g., tools like DrMemory, Memcheck Static analysis (find bugs without execution) Many tools for C/C++ with focus on memory errors Tools for Java that catch null pointer errors, unwanted mutation, etc. Proofs of correctness (theorems) Code reviews (people reading each other’s code)

Outline of Today’s Class Reference equality “Value” equality with .equals Equality and inheritance equals and hashCode Spring 15 CSCI 2600, A Milanova

Equality Simple idea: Many subtleties 2 objects are equal if they have the same value Many subtleties Same reference, or same value? Same rep or same abstract value? Remember the HW3 questions Equality in the presence of inheritance? Does equality hold just now or is it eternal? How can we implement equality efficiently? Spring 15 CSCI 2600, A Milanova

Equality: == and equals Java uses the reference model for class types class Point { int x; // x-coordinate int y; // y-coordinate Point(int x, int y) { this.x = x; this.y = y; } a = new Point(2,5); b = new Point(2,5); c = b; a b 2 5 2 5 c Hence, there are 2 ways (at least) to test for equality! == is the reference equality. Returns true of the 2 references point to the same object. .equals() is the “value” equality. It may relaxes the reference equality. If it is defined in a class, it specifies what it means for two objects of this class to be “equal”. If it is not defined in a class, then the class inherits Object.equals, which implements reference equality. x == y is false y == z is true x.equals(y) is false y.equals(z) is true true or false? a == b ? true or false? b == c ? true or false? a.equals(b) ? true or false? b.equals(c) ?

Equality: == and equals In Java, == tests for reference equality. This is the strongest form of equality Usually we need a weaker form of equality, value equality In our Point example, we want a to be “equal” to b because the a and b objects hold the same value Need to override Object.equals b c a b 2 5 2 5 Spring 15 CSCI 2600, A Milanova

Properties of Equality Equality is an equivalence relation Reflexive a.equals(a) Symmetric a.equals(b)  b.equals(a) Transitive a.equals(b)∧b.equals(c) a.equals(c) Is reference equality an equivalence relation? Yes Spring 15 CSCI 2600, A Milanova (based on slide by Michael Ernst)

Object.equals method Object.equals is very simple: public class Object { public boolean equals(Object obj) { return this == obj; } Point extends Object (all objects extend Object, implicitly).

Object.equals Javadoc spec Indicates whether some other object is "equal to" this one. The equals method implements an equivalence relation: It is reflexive: for any non-null reference value x, x.equals(x) should return true. It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true. It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true. It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.

Object.equals Javadoc spec For any non-null reference value x, x.equals(null) should return false. The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true)… Parameters: obj - the reference object with which to compare. Returns: true if this object is the same as the obj argument; false otherwise. See Also: hashCode(), HashMap

The Object.equals Spec Why this complex specification? Why not just returns: true if obj == this, false otherwise Object is the superclass for all Java classes The specification of Object.equals must be as weak (i.e., general) as possible Subclasses must be substitutable for Object Thus, subclasses need to provide stronger equals obj == this is too strong, the strongest form of equality! Places undue restriction on subclasses: no subclass can weaken equals and still be substitutable for Object! The spec lists the basic properties of equality, the weakest possible specification of equals

“Value” Equality public class Duration { private final int min; private final int sec; public Duration(int min, int sec) { this.min = min; this.sec = sec; } Duration d1 = new Duration(10,5); Duration d2 = new Duration(10,5); System.out.println(d1.equals(d2)); // prints? Spring 15 CSCI 2600, A Milanova (example due to Michael Ernst)

First Attempt to Add equals public class Duration { public boolean equals(Duration d) { return this.min == d.min && this.sec == d.sec; } Duration d1 = new Duration(10,5); Duration d2 = new Duration(10,5); System.out.println(d1.equals(d2)); Yields what? Is equals reflexive, symmetric and transitive? This equals is incorrect though. Why? Fix? Yields true. It is reflexive, symmetric and transitive, yes. Problem: we overloaded equals(), instead of overriding it. However, consider: Object d1 = new Duration(10,5); Object d2 = new Duration(10,5); System.out.println(d1.equals(d2)); Yields FALSE! Spring 15 CSCI 2600, A Milanova (example due to Michael Ernst)

What About This? public class Duration { public boolean equals(Duration d) { return this.min == d.min && this.sec == d.sec; } Object d1 = new Duration(10,5); Object d2 = new Duration(10,5); System.out.println(d1.equals(d2)); Yields what? d1’s compile-time type is Object. d1’s runtime type is Duration. Yields false! equals(Duration) overloads Object.equals. So now Duration has 2 equals method families. Because d1 and d2 are of declared (compile-time) type Object, the call d1.equals(d2) resolves to equals(Object) at compile time. At runtime, it calls Object.equals(Object). Compiler looks at d1’s compile-time type. Chooses signature equals(Object). Spring 15 CSCI 2600, A Milanova (example due to Michael Ernst)

A Correct equals @Override public boolean equals(Object o) { if (! (o instanceof Duration) ) return false; Duration d = (Duration) o; return this.min == d.min && this.sec == d.sec; } Object d1 = new Duration(10,5); Object d2 = new Duration(10,5); System.out.println(d1.equals(d2)); Yields what? Yields true. Now Duration.equals(Object) overrides Object.equals(Object). d1.equals(d2) calls Duration.equals(Object). Spring 15 CSCI 2600, A Milanova (example due to Michael Ernst)

Outline Reference equality “Value” equality with .equals Equality and inheritance equals and hashCode Spring 15 CSCI 2600, A Milanova

Add a Nano-second Field public class NanoDuration extends Duration { private final int nano; public NanoDuration(int min, int sec, int nano){ this.super(min,sec);// initializes min&sec this.nano = nano; } What if we inherit Duration.equals? What happens if we inherit Duration.equals? Spring 15 CSCI 2600, A Milanova (example due to Michael Ernst)

First Attempt at NanoDuration.equals public boolean equals(Object o) { if (! (o instanceof NanoDuration) ) return false; NanoDuration nd = (NanoDuration) o; return super.equals(nd) && nd.nano == nano; } Duration d1 = new NanoDuration(5,10,15); Duration d2 = new Duration(5,10); d1.equals(d2); Yields what? d2.equals(d1); Yields what? This is not good. It is not symmetric! d1.equals(d2) returns false. d2.equals(d1) returns true. Spring 15 CSCI 2600, A Milanova (example due to Michael Ernst)

Possible Fix for NanoDuration.equals public boolean equals(Object o) { if (! (o instanceof Duration) ) return false; if (! (o instanceof NanoDuration) ) return super.equals(o);//compare without nano NanoDuration nd = (NanoDuration) o; return super.equals(o) && nd.nano == nano; } Does it fix the symmetry bug? What can go wrong? It fixes the symmetry problem but it is not transitive! Spring 15 CSCI 2600, A Milanova (example due to Michael Ernst)

Possible Fix for NanoDuration.equals Duration d1 = new NanoDuration(10,5,15); Duration d2 = new Duration(10,5); Duration d3 = new NanoDuration(10,5,30); d1.equals(d2); Yields what? d2.equals(d3); Yields what? d1.equals(d3); Yields what? equals is not transitive! d1 d2 d3 10 5 15 d1.equals(d2); Yields true d2.equals(d3); Yields true d1.equals(d3); Yields false! Not transitive! 10 5 10 5 30 Spring 15 CSCI 2600, A Milanova (example due to Michael Ernst)

One Solution: Checking Exact Class, Instead of instanceof class Duration { public boolean equals(Object o) { if (o == null) return false; if ( !o.getClass().equals(getClass()) ) return false; Duration d = (Duration) o; return d.min == min && d.sec == sec; } Problem: every subclass must implement equals; sometimes, we want to compare distinct classes! Aside: Object.getClass() returns the exact runtime class of the receiver object. Spring 15 CSCI 2600, A Milanova (code example due to Michael Ernst)

Another Solution: Composition public class NanoDuration { private final Duration duration; private final int nano; … } Composition does solve the equals problem: Duration and NanoDuration are now unrelated, so we’ll never compare a Duration to a NanoDuration Problem: Can’t use NanoDuration instead of Duration. Can’t reuse code written for Duration. Spring 15 CSCI 2600, A Milanova (example due to Michael Ernst)

A Reason to Avoid Subclassing Concrete Classes. More later In the JDK, subclassing of concrete classes is rare. When it happens, there are problems One example: Timestamp extends Date Extends Date with a nanosecond value But Timestamp spec lists several caveats E.g., Timestamp.equals(Object) method is not symmetric with respect to Date.equals(Object) (the symmetry problem we saw on slide 20)

Abstract Classes There is no equality problem if superclass cannot be instantiated! E.g., if Duration were abstract, the issue of comparing Duration and NanoDuration never arises Prefer subclassing abstract classes Just like in real life. “Superclasses” in real life cannot be instantiated Spring 15 CSCI 2600, A Milanova (based on a slide by Michael Ernst)

Outline Reference equality “Value” equality with .equals Equality and inheritance equals and hashCode Spring 15 CSCI 2600, A Milanova

The int hashCode Method hashCode computes an index for the object (to be used in hashtables) Javadoc for Object.hashCode(): “Returns a hash code value of the object. This method is supported for the benefit of hashtables such as those provided by HashMap.” Self-consistent: o.hashCode() == o.hashCode() … as long as o does not change between the calls Consistent with equals() method: a.equals(b) => a.hashCode() == b.hashCode()

The Object.hashCode Method Object.hashCode’s implementation returns a distinct integer for each distinct object, typically by converting the object’s address into an integer hashCode must be consistent with equality equals and hashCode are used in hashtables If hashCode is inconsistent with equals, the hashtable behaves incorrectly Rule: if you override equals, override hashCode; must be consistent with equals

Implementations of hashCode Remember, we defined Duration.equals(Object) public class Duration { Choice 1: don’t override, inherit hashCode from Object Choice 2: public int hashCode() { return 1; } Choice 3: public int hashCode() { return min; } Choice 4: public int hashCode() { return min+sec; } } Choice 1: hashCode is inconsistent with equals. One of the most common mistakes by Java programmers is to override equals but not override hashCode. Choice 2: consistent with equals, but inefficient, groups all Duration objects into one bucket. Choice 3: consistent with equals, better prefiltering, but still inefficient because groups all durations with same min into one bucket. Choice 4: consistent with equals. Even better, will tend to change the hashCode as object value changes. Spring 15 CSCI 2600, A Milanova

hashCode Must Be Consistent with equals Suppose we change Duration.equals // Returns true if o and this represent the same number of // seconds public boolean equals(Object o) { if (!(o instanceof Duration)) return false; Duration d = (Duration) o; return 60*min+sec == 60*d.min+d.sec; } Can we leave hashCode be one of the implementations on the previous slide we deemed consistent? Choice 1 is inconsistent. Choice 2 is consistent, but not good because it groups all Durations in one bucket. Choice 3 is inconsistent, because we may have min:0, sec: 90 and min: 1, sec: 30, which are equal according to the new definition. Thus, we’ll have a.equals(b) true but a.hashCode == b.hashCode false, i.e., inconsistent. Choice 4 is inconsistent too because we again again may have a.equals(b) not imply a.hashCode == b.hashCode. We need to redefine hashCode. What will be a good one? return 60*min+sec. Spring 15 CSCI 2600, A Milanova (slide by Mike Ernst)