computer science 112 fundamentals of programming ii inheritance and abstract classes

27
Computer Science 112 Fundamentals of Programming II Inheritance and Abstract Classes

Upload: linette-banks

Post on 18-Dec-2015

222 views

Category:

Documents


0 download

TRANSCRIPT

Computer Science 112

Fundamentals of Programming IIInheritance and Abstract Classes

Classification in the Animal Kingdom

animal

mammal insect

bear cat dog ant cockroach tick

instances classes

Smokey Yogi Boo-Boo Spot Fido Billy Bob

Classification Among Artifacts: Vehicles

vehicle

car truck

sedan van suv pickup semi tow

bus

Classification in Software

• Classes are organized in a hierarchy (subclasses and superclasses)

• Subclasses inherit the attributes (data) and behavior (methods) of superclasses

• We can eliminate redundant data and code by factoring them up the hierarchy

• We can get behavior for free by subclassing

Example: Python’s object Classobject

str list dict

Example: Python’s object Classobject

str list

Array CounterArrayBag LinkedBag

dict

object implements a default __eq__ and __str__

These methods already work for any subclass

These methods can be overridden in any subclass

Finding the Right Method

• When a method is run on an object, the PVM looks for its code in the object’s class

• If the code not found there, the PVM looks in the object’s superclass

• etc., until the code is not found in object, whereupon an exception is raised

Redundant Code in the Bag Classes

They all implement the same interface (same method headers)

Do any method implementations look the same?

Do any instance variables and their values look the same?

LinkedBag ArrayBag

BagInterface

ArraySortedBag

Redundant Methods

The methods __init__, isEmpty, __len__, __str__,

__eq__, __iter__, clear, and remove are

exactly the same in ArrayBag and ArraySortedBag

ArrayBag

BagInterface

ArraySortedBag

Redundant Variables and Data

The variables DEFAULT_CAPACITY, self._size, and self._items are the same and refer to the same types of objects

ArrayBag

BagInterface

ArraySortedBag

Differences

The method __contains__ is an additional method in ArraySortedBag

The method add works differently in ArraySortedBag

The method __add__ creates an ArraySortedBag

ArrayBag

BagInterface

ArraySortedBag

Inheritance to the Rescue!Make ArraySortedBag a subclass of ArrayBag

ArraySortedBag includes just the methods __init__, __contains__, and add

ArraySortedBag inherits all of the data and the other methods from ArrayBag

ArrayBag

BagInterface

ArraySortedBag

means implements an interface

means is a subclass of another class

from arraybag import ArrayBag

class ArraySortedBag(ArrayBag): """An array-based sorted bag implementation."""

# Constructor def __init__(self, sourceCollection = None): """Sets the initial state of self, which includes the contents of sourceCollection, if it's present.""" ArrayBag.__init__(self, sourceCollection)

The New ArraySortedBag

ArrayBag.__init__ calls the __init__ method in the parent class, which sets up the bag’s data

Note that self is passed as an additional argument

from arraybag import ArrayBag

class ArraySortedBag(ArrayBag): """An array-based sorted bag implementation."""

# Accessor methods def __contains__(self, item): """Returns True if item is in self or False otherwise.""" # Performs a binary search for item in the # self.items array

The Method __contains__

The instance variables self._items and self._size are visible within the ArraySortedBag class

from arraybag import ArrayBag

class ArraySortedBag(ArrayBag): """An array-based sorted bag implementation."""

# Mutator methods def add(self, item): """Adds item to self.""" # Empty or last item, call ArrayBag.add if self.isEmpty() or \ item >= self._items[len(self) - 1]: ArrayBag.add(self, item) else: # Search for the first item >= new item

The Method add

ArrayBag.add refers to the add method in the parent class, which adds the item to the logical end of the array

Generalizing the __add__ Method

class ArrayBag(object):

def __add__(self, other): """Returns a new bag containing the contents of self and other.""" result = ArrayBag(self) for item in other: result.add(item) return result

We really need a clone of self, whose type is the same as the type of self (not necessarily an ArrayBag)

Generalizing the __add__ Method

class ArrayBag(object):

def __add__(self, other): """Returns a new collection containing the contents of self and other.""" result = type(self)(self) for item in other: result.add(item) return result

The type function returns the type of a given object

This method will now work for any type of collection!

Redundant Code in the Bag Classes

LinkedBag ArrayBag

BagInterface

ArraySortedBag

The methodsisEmpty, __len__, __str__, __add__, and __eq__ are exactly the same in ArrayBag and LinkedBag

The variable self._size refers to the same type of data

Redundant Code in the Bag Classes

LinkedBag ArrayBag

BagInterface

ArraySortedBag

The methodsisEmpty, __len__, __str__, __add__, and __eq__ are exactly the same in ArrayBag and LinkedBag

The variable self._size refers to the same type of data

AbstractBag

Factor redundant data and methods up to a new parent class

Abstract and Concrete Classes

• An abstract class defines data and methods common to all subclasses, but is rarely instantiated

• A concrete class inherits some data and methods and defines other data and methods; this class is instantiated

Leverage Abstraction

• __str__, __add__, __eq__, and isEmpty just call other methods to get their work done

• Try to use just method calls in your code; avoid direct references to instance variables as much as possible

• Such code will be more general and easier to push up in the hierarchy

Deeper Hierarchies

object

ArrayBag LinkedBag

AbstractBag

ArrayList LinkedList

AbstractList

Which methods are redundant?

ArraySortedBag ArraySortedList

Deeper Hierarchies

object

ArrayBag LinkedBag

AbstractBag

AbstractCollection

ArrayList LinkedList

AbstractList

Which methods are the redundant ones?

ArraySortedBag ArraySortedList

c.isEmpty()len(c) str(c) c1 + (c2)c1 == c2

AbstractCollection

• Includes data and behavior for any type of collection

• Maintains the logical size (len and isEmpty)

• Copies elements during instantiation

• Provides default implementations of the +, ==, and str operations

class AbstractCollection(object): """An abstract collection implementation."""

# Constructor def __init__(self, sourceCollection = None): """Sets the initial state of self, which includes the contents of sourceCollection, if it's present.""" self._size = 0 if sourceCollection: for item in sourceCollection: self.add(item)

AbstractCollection

Also defines the methods isEmpty, __len__, __str__, __add__, and __eq__

Using Inheritance

• Sometimes you’ll spot an opportunity to subclass under another class immediately (the GUI classes are good examples of this)

• Most of the time, you’ll develop a bunch of classes and realize only later that they have redundancies that can be factored into common superclasses (refactoring)

The Complete Collection Hierarchy

For Friday

Stacks

Chapter 7