CS3500: Object-Oriented Design Fall 2013

Similar documents
Subclassing for ADTs Implementation

Code Reuse: Inheritance

Exceptions and Design

Object-Oriented Design Lecture 13 CSU 370 Fall 2008 (Pucella) Friday, Oct 31, 2008

Java Object Oriented Design. CSC207 Fall 2014

CS/ENGRD 2110 SPRING Lecture 7: Interfaces and Abstract Classes

16 Multiple Inheritance and Extending ADTs

Computer Science CS221 Test 2 Name. 1. Give a definition of the following terms, and include a brief example. a) Big Oh

7 Code Reuse: Subtyping

Type Hierarchy. Comp-303 : Programming Techniques Lecture 9. Alexandre Denault Computer Science McGill University Winter 2004

Lecture 6. COMP1006/1406 (the OOP course) Summer M. Jason Hinek Carleton University

Object-Oriented Design Lecture 23 CS 3500 Fall 2009 (Pucella) Tuesday, Dec 8, 2009

Algebraic Specifications

Prelim 1 SOLUTION. CS 2110, September 29, 2016, 7:30 PM Total Question Name Loop invariants. Recursion OO Short answer

3 ADT Implementation in Java

Object-Oriented Design Lecture 11 CS 3500 Spring 2010 (Pucella) Tuesday, Feb 16, 2010

CS/ENGRD 2110 FALL Lecture 7: Interfaces and Abstract Classes

ITI Introduction to Computing II

Today s lecture. CS 314 fall 01 C++ 1, page 1

Inheritance. Transitivity

CS/ENGRD 2110 SPRING 2018

Contents. I. Classes, Superclasses, and Subclasses. Topic 04 - Inheritance

Why Design by Contract! CS 619 Introduction to OO Design and Development. Design by Contract. Fall 2012

CMSC131. Inheritance. Object. When we talked about Object, I mentioned that all Java classes are "built" on top of that.

Index. Index. More information. block statements 66 y 107 Boolean 107 break 55, 68 built-in types 107

Object-Oriented Design Lecture 3 CSU 370 Fall 2007 (Pucella) Friday, Sep 14, 2007

Java Fundamentals (II)

CS 61B Discussion 5: Inheritance II Fall 2014

Outline. Java Models for variables Types and type checking, type safety Interpretation vs. compilation. Reasoning about code. CSCI 2600 Spring

DATA STRUCTURES CHAPTER 1

CS350: Data Structures Stacks

17 From Delegation to Inheritance

Contracts. Dr. C. Constantinides. June 5, Department of Computer Science and Software Engineering Concordia University Montreal, Canada 1/71

Introduction & Java Review. EE 564 Lecture 1

public static void negate2(list<integer> t)

JML Class Specifications The Java Modeling Language (Part 2) A Java Class

15 Multiple Inheritance and Traits

JAVA MOCK TEST JAVA MOCK TEST II

13 Subtyping Multiple Types

17 Multiple Inheritance and ADT Extensions

CSC 1052 Algorithms & Data Structures II: Stacks

Polymorphism. return a.doublevalue() + b.doublevalue();

The Java Modeling Language (Part 2)

6.170 Lecture 7 Abstract Data Types MIT EECS

Stacks. Chapter 5. Copyright 2012 by Pearson Education, Inc. All rights reserved

+ Abstract Data Types

public static boolean isoutside(int min, int max, int value)

Data abstractions: ADTs Invariants, Abstraction function. Lecture 4: OOP, autumn 2003

Chapter 11 Inheritance and Polymorphism. Motivations. Suppose you will define classes to model circles,

Programming Languages and Techniques (CIS120)

STUDENT LESSON A20 Inheritance, Polymorphism, and Abstract Classes

Binghamton University. CS-140 Fall Problem Solving. Creating a class from scratch

Introduction to Computer Science II (ITI 1121) Midterm Examination

8 Hiding Implementation Details

Data Abstraction and Specification of ADTs

Prelim 1. CS 2110, September 29, 2016, 7:30 PM Total Question Name Loop invariants

ITI Introduction to Computing II

CS 112 Introduction to Computing II. Wayne Snyder Computer Science Department Boston University

20 Subclassing and Mutation

First IS-A Relationship: Inheritance

CS61B Spring 2016 Guerrilla Section 2 Worksheet

Data Structures and Algorithms in Java. Second Year Software Engineering

Inheritance and Polymorphism

CS412/CS413. Introduction to Compilers Tim Teitelbaum. Lecture 17: Types and Type-Checking 25 Feb 08

Type Hierarchy. Lecture 6: OOP, autumn 2003

Lab 2: Object-Oriented Design 12:00 PM, Jan 31, 2018

CSE 331 Final Exam 12/14/15 Sample Solution. Question 1. (20 points, 1 each) Warmup. For each statement, circle T if it is true and F if it is false.

ITI Introduction to Computing II

CS211 Spring 2005 Prelim 1 March 10, Solutions. Instructions

Object-Oriented Languages and Object-Oriented Design. Ghezzi&Jazayeri: OO Languages 1

ITI Introduction to Computing II

The Design Recipe Fall 2017

The Java Type System (continued)

Programming Languages and Techniques (CIS120)

Contents. Figures. Tables. Examples. Foreword. Preface. 1 Basics of Java Programming 1. xix. xxi. xxiii. xxvii. xxix

CS Internet programming Unit- I Part - A 1 Define Java. 2. What is a Class? 3. What is an Object? 4. What is an Instance?

EECS2030 Week 7 worksheet Tue Feb 28, 2017

Software Engineering Fall 2015 (CSC 4350/6350) TR. 5:30 pm 7:15 pm. Rao Casturi 11/03/2015

Media Computation. Lecture 16.1, December 8, 2008 Steve Harrison

More on Objects in JAVA TM

Inheritance (Part 5) Odds and ends

Object typing and subtypes

More about inheritance

Prelim 1. Solution. CS 2110, 14 March 2017, 7:30 PM Total Question Name Short answer

CS-202 Introduction to Object Oriented Programming

Generics in Java. EECS2030: Advanced Object Oriented Programming Fall 2017 CHEN-WEI WANG

Motivating Example: Observations (1) Generics in Java. Motivating Example: A Book of Objects. Motivating Example: Observations (2)

ITI Introduction to Computing II

CS 61B Spring 2017 Guerrilla Section 3 Solutions

CH. 2 OBJECT-ORIENTED PROGRAMMING

CS-140 Fall 2018 Test 2 Version A Nov. 12, Name:

Pages and 68 in [JN] conventions for using exceptions in Java. Chapter 8 in [EJ] guidelines for more effective use of exceptions.

CS159. Nathan Sprague

Java Classes, Inheritance, and Interfaces

More Relationships Between Classes

CS 61B Spring 2017 Guerrilla Section 3 Worksheet. 25 February 2017

Programming Languages and Techniques (CIS120)

CSIS 10B Lab 2 Bags and Stacks

M301: Software Systems & their Development. Unit 4: Inheritance, Composition and Polymorphism

Programming Languages and Techniques (CIS120)

Transcription:

CS3500: Object-Oriented Design Fall 2013 Class 3 9.13.2013

Plan for Today Web-CAT Announcements Review terminology from last class Finish Recipe implementation of StackInt as a class Abstraction Barrier and Interchangeable Parts Cover Liskov Chapters 1 and 2 Discuss Assignment 1 Start discussing Liskov Chapter 3 2

Abstract Data Type (ADT) What is an ADT? - set of data - set of operations - description of what operations do Within this course, when discuss ADTs, we will discuss them using: - a signature: names of operations and types - a specification: agreement between client and implementors 3

StackInt Signature empty: push: --> StackInt StackInt x int --> StackInt isempty: StackInt --> boolean top: StackInt --> int pop: StackInt --> StackInt size: StackInt --> int 4

StackInt Algebraic Specifications isempty (empty()) = true isempty (push (s, n)) = false top (push (s, n)) = n pop (push (s, n)) = s size (empty()) = 0 size (push (s, n)) = 1 + size (s) 5

Recipe Implementation of StackInt 6

StackInt Recipe Implementation Determine which operations of the ADT are basic creators, and which are other operations. Hints: -Except for the basic creators, each operation is specified by one or more equations. -The basic creators are used as arguments in the left side of the equations. empty: -> StackInt push: StackInt x int -> StackInt isempty: StackInt -> boolean top: StackInt -> int pop: StackInt -> StackInt size: StackInt -> int isempty (empty()) = true isempty (push (s, n)) = false top (push (s, n)) = n pop (push (s, n)) = s size (empty()) = 0 size (push (s, n)) = 1 + size (s) 7

StackInt Recipe Implementation Determine which operations of the ADT are basic creators, and which are other operations. Hints: -Except for the basic creators, each operation is specified by one or more equations. -The basic creators are used as arguments in the left side of the equations The basic creators are empty: -> StackInt push: StackInt x int -> StackInt isempty: StackInt -> boolean top: StackInt -> int pop: StackInt -> StackInt size: StackInt -> int isempty (empty()) = true isempty (push (s, n)) = false top (push (s, n)) = n pop (push (s, n)) = s size (empty()) = 0 size (push (s, n)) = 1 + size (s) empty and push. 8

StackInt Recipe Implementation Define an abstract class named T. 9

StackInt Recipe Implementation Define an abstract class named T. /** * StackInt represents a stack * of ints */ public abstract class StackInt { } 10

StackInt Recipe Implementation For each basic creator c of the ADT, define a concrete subclass of T. 11

StackInt Recipe Implementation For each basic creator c of the ADT, define a concrete subclass of T. /** * Empty represents a stack that * contains no ints */ class Empty extends StackInt {} /** * Push represents a non-empty * stack of ints */ class Push extends StackInt {} 12

StackInt Recipe Implementation For each concrete subclass, declare instance empty: -> StackInt push: StackInt x int -> StackInt variables with the same types and names as the arguments that are passed to the corresponding basic creator c. 13

StackInt Recipe Implementation For each concrete subclass, declare instance variables with the same types and names as the arguments that are passed to the corresponding basic creator c. empty: -> StackInt push: StackInt x int -> StackInt /** * Empty represents a stack that * contains no ints */ class Empty extends StackInt {} /** * Push represents a non-empty * stack of ints */ class Push extends StackInt { /** other elements of this StackInt */ StackInt s; /** topmost element of this StackInt */ int n; } 14

StackInt Recipe Implementation For each concrete subclass, define a Java empty: -> StackInt push: StackInt x int -> StackInt constructor that takes the same arguments as the basic creator c and stores those arguments into the instance variables. 15

StackInt Recipe Implementation For each concrete subclass, define a Java constructor that takes the same arguments as the basic creator c and stores those arguments into the instance variables. empty: -> StackInt push: StackInt x int -> StackInt /** * Constructor for Empty */ Empty () { } /** * Constructor for Push * @param s the stack without topmost * element * @param n is the topmost element of the * stack */ Push (StackInt s, int n) { this.s = s; this.n = n; } 16

StackInt Recipe Implementation For each operation f of the ADT that is not a basic creator, declare an abstract method f in the abstract class T. The explicit arguments of the abstract method f should be the same as the arguments of the operation f, except the abstract method f will take one less argument than f. That missing argument will be the receiver for calls to the abstract method f (so that argument will still be available to the abstract method f, as the value of Java's special variable this). That missing argument should be of type T. If the operation f has more than one argument of type T, so you have some choice as to which argument to omit, then you should omit the argument that discriminates between the various equations for f in the algebraic specification. empty: -> StackInt push: StackInt x int -> StackInt isempty: StackInt -> boolean top: StackInt -> int pop: StackInt -> StackInt size: StackInt -> int isempty (empty()) = true isempty (push (s, n)) = false top (push (s, n)) = n pop (push (s, n)) = s size (empty()) = 0 size (push (s, n)) = 1 + size (s) 17

StackInt Recipe Implementation For each operation f of the ADT that is not a basic creator, declare an abstract method f in the abstract class T. The explicit arguments of the abstract method f should be the same as the arguments of the operation f, except the abstract method f will take one less argument than f. That missing argument will be the receiver for calls to the abstract method f (so that argument will still be available to the abstract method f, as the value of Java's special variable this). That missing argument should be of type T. If the operation f has more than one argument of type T, so you have some choice as to which argument to omit, then you should omit the argument that discriminates between the various equations for f in the algebraic specification. empty: -> StackInt push: StackInt x int -> StackInt isempty: StackInt -> boolean top: StackInt -> int pop: StackInt -> StackInt size: StackInt -> int isempty (empty()) = true isempty (push (s, n)) = false top (push (s, n)) = n pop (push (s, n)) = s size (empty()) = 0 size (push (s, n)) = 1 + size (s) 18

StackInt Recipe Implementation For each operation f of the ADT that is not a basic creator, declare an abstract method f in the abstract class T. The explicit arguments of the abstract method f should be the same as the arguments of the operation f, except the abstract method f will take one less argument than f. That missing argument will be the receiver for calls to the abstract method f (so that argument will still be available to the abstract method f, as the value of Java's special variable this). That missing argument should be of type T. If the operation f has more than one argument of type T, so you have some choice as to which argument to omit, then you should omit the argument that discriminates between the various equations for f in the algebraic specification. empty: -> StackInt push: StackInt x int -> StackInt isempty: StackInt -> boolean top: StackInt -> int pop: StackInt -> StackInt size: StackInt -> int abstract boolean isemptymethod (); abstract int topmethod (); abstract StackInt popmethod (); abstract int sizemethod (); 19

StackInt Recipe Implementation For each operation of the ADT, define a static method within the abstract class. -If the operation is a basic creator c, then the static method for c should create and return a new instance of the subclass that corresponds to c. -If the operation is not a basic creator, then the static method for c should delegate to the corresponding abstract method for c, passing it all but one of its arguments. (The missing argument will be available to the abstract method via the special variable named this.) Suppose, for example, that the static method T.f is called with arguments x1, x2, x3, and x4, where x1 is the only argument of type T. Then the body of T.f should be: return x1.f (x2, x3, x4); empty: -> StackInt push: StackInt x int -> StackInt isempty: StackInt -> boolean top: StackInt -> int pop: StackInt -> StackInt size: StackInt -> int 20

StackInt Recipe Implementation For each operation of the ADT, define a static method within the abstract class. -If the operation is a basic creator c, then the static method for c should create and return a new instance of the subclass that corresponds to c. -If the operation is not a basic creator, then the static method for c should delegate to the corresponding abstract method for c, passing it all but one of its arguments. (The missing argument will be available to the abstract method via the special variable named this.) Suppose, for example, that the static method T.f is called with arguments x1, x2, x3, and x4, where x1 is the only argument of type T. Then the body of T.f should be: return x1.f (x2, x3, x4); empty: -> StackInt push: StackInt x int -> StackInt isempty: StackInt -> boolean top: StackInt -> int pop: StackInt -> StackInt size: StackInt -> int 21

StackInt Recipe Implementation For each operation of the ADT, define a static method within the abstract class. -If the operation is a basic creator c, then the static method for c should create and return a new instance of the subclass that corresponds to c. -If the operation is not a basic creator, then the static method for c should delegate to the corresponding abstract method for c, passing it all but one of its arguments. (The missing argument will be available to the abstract method via the special variable named this.) Suppose, for example, that the static method T.f is called with arguments x1, x2, x3, and x4, where x1 is the only argument of type T. Then the body of T.f should be: return x1.f (x2, x3, x4); empty: -> StackInt push: StackInt x int -> StackInt isempty: StackInt -> boolean top: StackInt -> int pop: StackInt -> StackInt size: StackInt -> int public static StackInt empty () { return new Empty (); } public static StackInt push (StackInt s, int n) { return new Push (s, n); } 22

StackInt Recipe Implementation For each operation of the ADT, define a static method within the abstract class. -If the operation is a basic creator c, then the static method for c should create and return a new instance of the subclass that corresponds to c. -If the operation is not a basic creator, then the static method for c should delegate to the corresponding abstract method for c, passing it all but one of its arguments. (The missing argument will be available to the abstract method via the special variable named this.) Suppose, for example, that the static method T.f is called with arguments x1, x2, x3, and x4, where x1 is the only argument of type T. Then the body of T.f should be: return x1.f (x2, x3, x4); empty: -> StackInt push: StackInt x int -> StackInt isempty: StackInt -> boolean top: StackInt -> int pop: StackInt -> StackInt size: StackInt -> int 23

StackInt Recipe Implementation For each operation of the ADT, define a static method within the abstract class. -If the operation is a basic creator c, then the static method for c should create and return a new instance of the subclass that corresponds to c. -If the operation is not a basic creator, then the static method for c should delegate to the corresponding abstract method for c, passing it all but one of its arguments. (The missing argument will be available to the abstract method via the special variable named this.) Suppose, for example, that the static method T.f is called with arguments x1, x2, x3, and x4, where x1 is the only argument of type T. Then the body of T.f should be: return x1.f (x2, x3, x4); empty: -> StackInt push: StackInt x int -> StackInt isempty: StackInt -> boolean top: StackInt -> int pop: StackInt -> StackInt size: StackInt -> int public static boolean isempty (StackInt s) { return s.isemptymethod(); } public static int top (StackInt s) { return s.topmethod(); } public static StackInt pop (StackInt s) { return s.popmethod(); } public static int size (StackInt s) { return s.sizemethod(); } 24

StackInt Recipe Implementation For each concrete subclass C of T, define all of the abstract methods that were declared within the abstract base class for T. (These definitions define dynamic (as opposed to static) methods.) For each abstract method f that is defined within a subclass C, the body of f should return the value specified by the algebraic specification for the case in which Java s special variable this will be an instance of the class C. -If the algebraic specification contains only one equation that describes the result of an operation f applied to an instance of C, and that equation has no side conditions, then the body of the dynamic method f should return the value expressed by the right hand side of that equation. -If the algebraic specification does not contain any equations that describe the result of an operation f applied to an instance of C, then the body of the dynamic method f should throw a RuntimeException such as an IllegalArgumentException. -(Note that other conditions are listed in the recipe.} empty: -> StackInt push: StackInt x int -> StackInt isempty: StackInt -> boolean top: StackInt -> int pop: StackInt -> StackInt size: StackInt -> int isempty (empty()) = true isempty (push (s, n)) = false top (push (s, n)) = n pop (push (s, n)) = s size (empty()) = 0 size (push (s, n)) = 1 + size (s) 25

StackInt Recipe Implementation For each concrete subclass C of T, define all of the abstract methods that were declared within the abstract base class for T. (These definitions define dynamic (as opposed to static) methods.) For each abstract method f that is defined within a subclass C, the body of f should return the value specified by the algebraic specification for the case in which Java s special variable this will be an instance of the class C. -If the algebraic specification contains only one equation that describes the result of an operation f applied to an instance of C, and that equation has no side conditions, then the body of the dynamic method f should return the value expressed by the right hand side of that equation. isempty (empty()) = true isempty (push (s, n)) = false top (push (s, n)) = n pop (push (s, n)) = s size (empty()) = 0 size (push (s, n)) = 1 + size (s) class Empty extends StackInt { Empty () { } boolean isemptymethod () { return true; } int topmethod () { String msg1 = "attempted to compute the top of an empty + StackInt"; throw new RuntimeException (msg1); } -If the algebraic specification does not contain any equations that describe the result of an operation f applied to an instance of C, then the body of the dynamic method f should throw a RuntimeException such as an IllegalArgumentException. -(Note that other conditions are listed in the recipe.} 26 } StackInt popmethod () { } String msg1 = "attempted to pop from an empty StackInt"; throw new RuntimeException (msg1); int sizemethod () { } return 0;

StackInt Recipe Implementation For each concrete subclass C of T, define all of the abstract methods that were declared within the abstract base class for T. (These definitions define dynamic (as opposed to static) methods.) For each abstract method f that is defined within a subclass C, the body of f should return the value specified by the algebraic specification for the case in which Java s special variable this will be an instance of the class C. -If the algebraic specification contains only one equation that describes the result of an operation f applied to an instance of C, and that equation has no side conditions, then the body of the dynamic method f should return the value expressed by the right hand side of that equation. -If the algebraic specification does not contain any equations that describe the result of an operation f applied to an instance of C, then the body of the dynamic method f should throw a RuntimeException such as an IllegalArgumentException. -(Note that other conditions are listed in the recipe.} isempty (empty()) = true isempty (push (s, n)) = false top (push (s, n)) = n pop (push (s, n)) = s size (empty()) = 0 size (push (s, n)) = 1 + size (s) class Push extends StackInt{ StackInt s; int n; } Push(StackInt s, int n){ this.s = s; this.n = n; } boolean isemptymethod(){ return false; } int topmethod(){ return n; } StackInt popmethod(){ return s; } int sizemethod(){ return 1 + size(s); } 27

Abstract Class vs. Concrete Class Concrete class: full implementation of the type. Abstract classes: at most a partial implementation of the type 28

Abstraction Barrier Every piece of software has, or should have, an abstraction barrier that divides the world into two parts: clients and implementors. - The clients are those who use the software. They do not need to know how the software works. - The implementors are those who build it. They need to know how the software works. 29

Interchangeable Parts [history.com] 18th century: Guns were made by hand, which meant each gun was one-of-a-kind. To repair a gun, a part had to be made especially for it. Mid-18th century a French gunsmith Honoré LeBlanc suggested the gun parts be made from standardized patterns, so that all gun parts would follow the same design and could be easily replaced if broken. Early 19th century, Eli Whitney manufacturing muskets production of large numbers of identical parts quickly and at a relatively low cost. The U.S. introduced the first large-scale assembly of weapons with its adoption of the Model 1842 musket, and the new arms industry would produce hundreds of thousands of rifles for Civil War soldiers, all from interchangeable parts. 30

31 Image from: http://www.cesura17.net/~will/pictures/places/images/2012csc3.jpg

Liskov Chapter 2 32

Type Checking Type safety Strongly type checking 33

Type Hierarchy [Liskov, p.27, Sidebar 2.4] Java supports type hierarchy, in which one type can be the supertype of other types, which are its subtypes. A subtype s objects have all the methods defined by the supertype. All object types are subtypes of Object, which is the top of the type hierarchy. Object defines a number of methods, including equals and tostring. Every object is guaranteed to have these methods. The apparent type of a variable is the type understood by the compiler from information available in declarations. The actual type of an object is its real type the type it receives when it is created. Java guarantees that the apparent type of an expression is a super type of its actual type. 34

Abstraction 35

Assignment 1 Due: Tuesday, September 17, 2013 at 11:59 pm Recipe implementation in Java of the FSetString ADT FSetString is an immutable abstract data type whose values represent finite sets with elements of type String. 36

Recipe Assumption Except for the basic creators, each operation is specified by one or more equations. If an operation is specified by more than one equation, then the left hand sides of the equations differ according to which basic creator was used to create an argument of type T. 37

Recipe Assumption Except for the basic creators, each operation is specified by one or more equations. If an operation is specified by more than one equation, then the left hand sides of the equations differ according to which basic creator was used to create an argument of type T. FSetString.add(s0, k0) = s0 if FSetString.contains(s0, k0) FSetString.add(s0, k0) = FSetString.insert(s0, k0) if!(fsetstring.contains(s0, k0)) 38

Recipe Assumption The operations of the ADT are to be implemented as static methods of a class named T. 39

equals method If s1 is a value of the FSetString ADT, then s1.equals(null) returns false. If s1 is a value of the FSetString ADT, but x is not, then s1.equals(x) returns false. If s1 and s2 are values of the FSetString ADT, then s1.equals(s2) if and only if for every String k FSetString.contains(s1, k) if and only if FSetString.contains(s2, k) 40

Theorem The following conditions are equivalent: 1. for every String k, FSetString.contains (s1, k) if and only if FSetString.contains (s2, k) 2. FSetString.isSubset (s1, s2) and FSetString.isSubset (s2, s1) 41

hashcode method If s1 and s2 are values of the FSetString ADT, and s1.equals(s2), then s1.hashcode() == s2.hashcode(). 42