220 likes | 333 Views
Computer Science 112. Fundamentals of Programming II Interfaces and Implementations. What Is an Interface?. The public or external view of a resource What you see when you run help on a resource Example: Python ’ s math module – a set of function names and constant names.
E N D
Computer Science 112 Fundamentals of Programming II Interfaces and Implementations
What Is an Interface? • The public or external view of a resource • What you see when you run help on a resource • Example: Python’s math module – a set of function names and constant names
What Is an Implementation? • The private or internal view of a resource • What you see when you examine the full code of a resource Interface def fib(n): """Returns the nth Fibonacci number.""" if n == 1 or n == 2: return 1 else: return fib(n – 1) + fib(n – 2) Implementation
Types of Interfaces • Function – The function’s header and docstring • Class –The class and method headers and docstrings • Module –The class and function headers
Interface and Implementation • Users and implementers have different responsibilities • A interface provides an abstraction barrier between users and implementers User’s code Interface Implementer’s code
Why the Barrier? • The resource is easier to learn • Can plug and play resources • Can provide several implementations of the same resource (polymorphism) • Can maintain a resource without disturbing users’ code
Example Resource: A Bag Collection • A bag is a container where you can put things, see if they’re there, visit them all, or remove each one • There is one interface or set of methods for all bag implementations • Two common implementations use an array or a linked structure
UML Class Diagram for Bags BagInterface means implements an interface LinkedBag ArrayBag The Unified Modeling Language is a way of describing relationships among resources visually
The Interface for All Bags b.isEmpty() Returns True if empty, False otherwise len(b) Returns the number of items in the bag str(b) Returns a string representation of the bag item in b Returns True if item is present in the bag, or False otherwise foritem in b: Visit each item in the bag b.add(item) Adds item to the bag b.remove(item) Removes item from the bag b.clear() Removes all items from the bag b1 + b2 Combines items in a new bag and returns it b == anything True if equal, False otherwise
Actual Methods in Python b.isEmpty() isEmpty(self) len(b) __len__(self) str(b) __str__(self) item in b __contains__(self, item) foritem in b: __iter__(self) b.add(item) add(self, item) b.remove(item) remove(self, item) b.clear() clear(self) b1 + b2 __add__(self, other) b == anything __eq__(self, other)
Bag Implementations • Array-based • Linked structure • Always a single set of abstract operations bag1 = LinkedBag() bag2 = ArrayBag([1, 2, 3, 4])
Example Use of a Bag bag = LinkedBag() # or ArrayBag() bag.add("A string") bag.add("Another string") for item in bag: print(item) secondBag = LinkedBag(bag) thirdBag = bag + secondBag print(secondBag == thirdBag) for item in bag: secondBag.remove(item) print(len(secondBag)) We have a single set of abstract operations and two implementing classes, ArrayBag and LinkedBag
Docstrings and Preconditions A docstring states what the method does. A precondition states what must be true for a method to run correctly. The method raises an exception if a precondition is not true. defremove(self, item): """Removes item from self. Precondition: item is in self. Raises: KeyError if item is not in self."""
Implementation: Data • The first step is to decide what the attributes are and represent these using the appropriate data • Will name these data with class or instance variables • The __init__ method sets these up
Composition and Aggregation BagInterface * Node LinkedBag ArrayBag Array means “is composed of” * means “aggregates zero or more within”
Data for ArrayBag from arrays import Array classArrayBag(object): """An array-based bag implementation.""" # Class variable DEFAULT_CAPACITY = 10 # Constructor def__init__(self, sourceCollection = None): """Sets the initial state of self, which includes the contents of sourceCollection, if it's present.""" self._items = Array(ArrayBag.DEFAULT_CAPACITY) self._size = 0 ifsourceCollection: for item insourceCollection: self.add(item)
Some Accessor Methods # Accessor methods defisEmpty(self): """Returns True if len(self) == 0, or False otherwise.""" returnlen(self) == 0 def__len__(self): """Returns the number of items in self.""" returnself._size def__str__(self): """Returns the string representation of self.""" return "{" + ", ".join(map(str, self)) + "}" Try to run methods within an implementation, rather than accessing variables directly.
Some Mutator Methods # Mutator methods defclear(self): """Makes self become empty.""" self._size = 0 self._items = Array(ArrayBag.DEFAULT_CAPACITY) defadd(self, item): """Adds item to self.""" # Resize the array here if necessary self._items[len(self)] = item self._size += 1
Data for LinkedBag from node import Node classLinkedBag(object): """A link-based bag implementation.""" # Constructor def__init__(self, sourceCollection = None): """Sets the initial state of self, which includes the contents of sourceCollection, if it's present.""" self._items = None self._size = 0 ifsourceCollection: for item insourceCollection: self.add(item)
Some Accessor Methods # Accessor methods defisEmpty(self): """Returns True if len(self) == 0, or False otherwise.""" returnlen(self) == 0 def__len__(self): """Returns the number of items in self.""" returnself._size def__str__(self): """Returns the string representation of self.""" return "{" + ", ".join(map(str, self)) + "}" Hooray! No changes from the same methods in ArrayBag!
Some Mutator Methods # Mutator methods defclear(self): """Makes self become empty.""" self._size = 0 self._items = None defadd(self, item): """Adds item to self.""" self._items = Node(item, self._items) self._size += 1 The container is now a linked structure, so it must be manipulated differently.
For Friday Iterators