computer science 112 fundamentals of programming ii interfaces and implementations
TRANSCRIPT
Computer Science 112
Fundamentals of Programming IIInterfaces 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
def fib(n): """Returns the nth Fibonacci number.""" if n == 1 or n == 2: return 1 else: return fib(n – 1) + fib(n – 2)
Interface
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
LinkedBag ArrayBag
BagInterface
The Unified Modeling Language is a way of describing relationships among resources visually
means implements an interface
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
for item 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
The Interface for All Bags
b.isEmpty() isEmpty(self)
len(b) __len__(self)
str(b) __str__(self)
item in b __contains__(self, item)
for item 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)
Actual Methods in Python
Bag Implementations
• Array-based
• Linked structure
• Always a single set of abstract operations
bag1 = LinkedBag()
bag2 = ArrayBag([1, 2, 3, 4])
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))
Example Use of a Bag
We have a single set of abstract operations and two implementing classes, ArrayBag and LinkedBag
Docstrings and Preconditions
def remove(self, item): """Removes item from self. Precondition: item is in self. Raises: KeyError if item is not in self."""
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.
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
means “is composed of”
LinkedBagNode*
ArrayBag
BagInterface
Array
* means “aggregates zero or more within”
from arrays import Array
class ArrayBag(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 if sourceCollection: for item in sourceCollection: self.add(item)
Data for ArrayBag
# Accessor methodsdef isEmpty(self): """Returns True if len(self) == 0, or False otherwise.""" return len(self) == 0 def __len__(self): """Returns the number of items in self.""" return self._size
def __str__(self): """Returns the string representation of self.""" return "{" + ", ".join(map(str, self)) + "}"
Some Accessor Methods
Try to run methods within an implementation, rather than accessing variables directly.
# Mutator methodsdef clear(self): """Makes self become empty.""" self._size = 0 self._items = Array(ArrayBag.DEFAULT_CAPACITY)
def add(self, item): """Adds item to self.""" # Resize the array here if necessary self._items[len(self)] = item self._size += 1
Some Mutator Methods
from node import Node
class LinkedBag(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 if sourceCollection: for item in sourceCollection: self.add(item)
Data for LinkedBag
# Accessor methodsdef isEmpty(self): """Returns True if len(self) == 0, or False otherwise.""" return len(self) == 0 def __len__(self): """Returns the number of items in self.""" return self._size
def __str__(self): """Returns the string representation of self.""" return "{" + ", ".join(map(str, self)) + "}"
Some Accessor Methods
Hooray! No changes from the same methods in ArrayBag!
# Mutator methodsdef clear(self): """Makes self become empty.""" self._size = 0 self._items = None
def add(self, item): """Adds item to self.""" self._items = Node(item, self._items) self._size += 1
Some Mutator Methods
The container is now a linked structure, so it must be manipulated differently.
For Friday
Iterators