week 10-11 inheritance and polymorphism. introduction classes allow you to modify a program without...

Post on 28-Dec-2015

217 Views

Category:

Documents

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Week 10-11

Inheritance and Polymorphism

Introduction

• Classes allow you to modify a program without really making changes to it.

• To elaborate, by subclassing a class, you can change the behavior of the program by simply adding new components to it rather than rewriting the existing components.

Introduction

• As we’ve seen, an instance of a class inherits the attributes of that class.

• However, classes can also inherit attributes from other classes.

• Hence, a subclass inherits from a superclass allowing you to make a generic superclass that is specialized via subclasses.

• The subclasses can override the logic in a superclass, allowing you to change the behavior of your classes without changing the superclass at all.

Inheritance

• In object-oriented programming (OOP), inheritance is when an object or class is based on another object or class, using the same implementation, it is a mechanism for code reuse.

• The relationships of objects or classes through inheritance give rise to a hierarchy.

• Inheritance was invented in 1967 for Simula.

Inheritance

• In some languages, inheritance implements IS-A Relationship.

• There are various types of inheritance, depending on paradigm and specific language.

Types of Inheritance

• Single Inheritance can inherit from only a single other object or class.

• Multiple Inheritance can inherit from multiple other objects or classes.

• The hierarchy in single inheritance is a tree, while in multiple inheritance it is a lattice.

Tree

Lattice

Types of Inheritance

• Classical inheritance is used in class-based programming, where objects are defined by classes, and classes can inherit attributes and implementation (i.e., previously coded algorithms associated with a class) from pre-existing classes called base classes, superclasses, or parent classes.

• The resulting classes are known as derived classes, subclasses, or child classes, and the resulting hierarchy is known as a class hierarchy.

Types of Inheritance

• Differential inheritance is used in prototype-based programming, where objects inherit directly from other objects.

Subclasses and superclasses

• A Subclass, "derived class", heir class, or child class is a modular, derivative class that inherits one or more language entities from one or more other classes (called superclasses, base classes, or parent classes).

cont

• The semantics of class inheritance vary from language to language, but commonly the subclass automatically inherits the instance variables and member functions of its superclasses.

• Some languages support the inheritance of other construct as well. For example, in Eiffel, contracts which define the specification of a class are also inherited by heirs.

cont

• The superclass establishes a common interface and foundational functionality, which specialized subclasses can inherit, modify, and supplement.

• The software inherited by a subclass is considered reused in the subclass.

• A reference to an instance of a class may actually be referring one of its subclasses.

cont

• The actual class of the object being referenced is impossible to predict at compile-time.

• A uniform interface is used to invoke the member functions of objects of a number of different classes.

• Subclass may replace superclass functions with entirely new functions that must share the same method signature.

Uninheritable Class

• In some languages a class may be declared as uninheritable by adding certain class modifiers to the class declaration.

• Examples include the "final" keyword in Java or the "sealed" keyword in C#. Such modifiers are added to the class declaration before the "class" keyword and the class identifier declaration.

• Such sealed classes restrict reusability, particularly when developers only have access to precompiled binaries and not source code.

Using Inheritance

• Implementation inheritance is the mechanism whereby a subclass re-uses code in a base class.

• By default the subclass retains all of the operations of the base class, but the subclass may override some or all operations, replacing the base-class implementation with its own.

Superclass

• Defining a superclass:• class FirstClass : #define the superclass• def setdata( self , value) : #define methods

self . data = value #’ self ’ refers to an instance def display( self ) : print(self . data)

Subclass

• Defining a subclass:• class SecondClass(FirstClass ) : #inherits from

#FirstClass def display( self ) : #redefines ’display ’ print("Current value = ’%s ’" % self . data)

cont

• As you can see, SecondClass “overwrites” the display method.

• When a FirstClass instance is created, all of its actions will be taken from the methods defined in FirstClass.

• When a SecondClass instance is created, it will use the inherited setdata() method from FirstClass but the display method will be the one from SecondClass.

Example Continue

• To make this easier to understand, here are some examples in practice.

• >>>x=FirstClass () #instance of FirstClass >>>y=SecondClass() #instance of SecondClass >>>x. setdata("The boy called Brian .")

• >>>y. setdata (42) • >>>x. display () • The boy called Brian . • >>>y. display () • Current value = ’42 ’

Explainantion

• Both instances (x and y) use the same setdata() method from FirstClass; x uses it because it’s an instance of FirstClass while y uses it because SecondClass inherits setdata() from FirstClass.

• However, when the display method is called, x uses the definition from First- Class but y uses the definition from SecondClass, where display is overridden.

cont

• Because changes to program logic can be made via subclasses, the use of classes generally supports code reuse and extension better than traditional functions do.

• Functions have to be rewritten to change how they work whereas classes can just be subclassed to redefine methods.

Redefining Methods

• Very similar to over-riding methods in Java • To redefine a method of the parent class,

include a new definition using the same name in the subclass.

• The old code won’t get executed. • To execute the method in the parent class in

addition to new code for some method, explicitly call the parent’s version of the method.

cont

• parentClass.methodName(self, a, b, c) • The only time you ever explicitly pass ‘self’ as

an argument is when calling a method of an ancestor.

Extending __init__

• Very similar to Java• Commonly, the ancestor’s __init__ method is

executed in addition to new commands.• Must be done explicitly• You’ll often see something like this in the

__init__ method of subclasses: • parentClass.__init__(self, x, y) • where parentClass is the name of the parent’s

class.

Example• class Person: def speak(self): print(“I can speak”) class Man(Person): def wear(self): print(“I wear shirt”) class Woman(Person): def wear(self): print(“I wear skirt”) man = Man() man.wear() man.speak()>>> I wear shirt I can speak

Multiple Inheritance

• Python supports a limited form of multiple inheritance.

• A class definition with multiple base classes looks as follows:

• class DerivedClass(Base1, Base2, Base3 …)

<statement-1> <statement-2> …

cont

• The only rule necessary to explain the semantics is the resolution rule used for class attribute references.

• This is depth-first, left-to-right. • Thus, if an attribute is not found in

DerivedClass, it is searched in Base1, then recursively in the classes of Base1, and only if it is not found there, it is searched in Base2, and so on.

Example of Multiple Inheritance• class A:• def A(self):• print(“I am A”)• class B:• def A(self):• print(“I am a”)• def B(self):• print(“I am B”)• class C(A, B):• def C(self):• print(“I am C”)• C = C()• C.A()• C.B()• C.C()

Explanation

• C multiple-inherit A and B, but since A is in the left of B, so C inherit A and invoke A.A() according to the left-to-right sequence.

• To implement C.B(), class A does not have B() method, so C inherit B for the second priority. So C.B() actually invokes B() in class B.

Method Overriding

• Method overriding means having a different implementation of the same method in the inherited class.

• These two methods would have the same signature, but different implementation.

• One of these would exist in the base class and another in the derived class. These cannot exist in the same class.

Overriding Method Definitions

• In a derived class, if you include a method definition that has the same name and exactly the same number and types of parameters as a method already defined in the base class, this new definition replaces the old definition of the method.

Explanation

• A subclass inherits methods from a superclass. Sometimes, it is necessary for the subclass to modify the methods defined in the superclass. This is referred to as method overriding.

• The following example demonstrates method overriding.

Example

• import math• class Circle:• # declaring the instance variable • radius = 0.0 • def Circle(self, radius):• self.radius = radius• # other method definitions here• def getArea(self):• #this method returns the area of the circle

return math.pi*pow(self.radius,2)

cont

• When the getArea method is invoked from an instance of the Circle class, the method returns the area of the circle.

• The next step is to define a subclass to override the getArea() method in the Circle class.

• The derived class will be the Cylinder class.• The getArea() method in the Circle class computes

the area of a circle, while the getArea method in the Cylinder class computes the surface area of a cylinder.

Derived Class• class Cylinder(Circle):• # declaring the instance variable• length = 0.0• def Cylinder(self, radius, length):• self.radius = radius• self.length = length• Circle(self.radius)• # other method definitions here• def getArea(self):• #this method returns the cylinder surface area• return 2*Circle.getArea(self) + 2*math.pi*self.radius*self.length

Test Code

• When the overriden method (getArea) is invoked for an object of the Cylinder class, the new definition of the method is called and not the old definition from the superclass(Circle).

Test Code

• MyCircle = Circle(1.2)• MyCylinder = Cylinder(1.2, 2.5)• A = MyCircle.getArea()• B = MyCylinder.getArea()• print(“Area of the circle is: “, A)• print(“Area of the cylinder is: “, B)

Association

• In object-oriented programming, association defines a relationship between classes of objects that allows one object instance to cause another to perform an action on its behalf. This relationship is structural, because it specifies that objects of one kind are connected to objects of another and does not represent behaviour.

Association

• In generic terms, the causation is usually called "sending a message", "invoking a method" or "calling a member function" to the controlled object.

• Concrete implementation usually requires the requesting object to invoke a method or member function using a reference or pointer to the memory location of the controlled object.

Association

• The objects that are related via the association are considered to act in a role with respect to the association, if object's current state in the active situation allows the other associated objects to use the object in the manner specified by the role. A role can be used to distinguish two objects of the same class when describing its use in the context of the association. A role describes the public aspects of an object with respect to an association.

Association

• Association implements USES-A Relationship

Protected Access Levels

• Generations of Pythonistas have mangled their variables with a double underscore "__" to enable data hiding as in C++ or Java. But this was always only an adaequate solution for preventing name clashes between a class and its superclass. The term "privacy" had a very different meaning.

Protected Access Levels

• Opposite to the standard semantics where each Python variable is essentially public, applying the above recipe it becomes basically "protected" i.e. visible only to the class where it is defined and to subclasses. In order to make an attribute public it has to be made public explicitely using either the public() decorator ( for methods only ) or the class attribute __public__.

Tip

• Remember Private, Public, Data Hiding?

Polymorphism

• Polymorphism exists when you define a number of subclasses which have commonly named methods.

• In some languages, it is essential that the polymorphic classes have the same interface (or be subinterfaces of a common parent interface), or be subclasses of a common superclass.

• This is sometimes called "strong, hierarchical typing", since the type rules are very rigid and follow the subclass/subinterface hierarchy.

Polymorphism

• Let’s look at the examples for Card, FaceCard, and Ace, we see that all three classes have the same method names, but have different implementations for some of these methods.

• These three classes are polymorphic. • A client class like Hand can contain individual

objects of any of the subclasses of Card. • A function can evaluate these polymorphic

methods without knowing which specific subclass is being invoked.

Class Card

• class Card( object ): • """A standard playing card for Blackjack.""" def __init__( self,

r, s ): self.rank, self.suit = r, s self.pval= r def __str__( self ): return "%2d%s" % ( self.rank, self.suit ) def getHardValue( self ): return self.pval def getSoftValue( self ): return self.pval

Class FaceCard

• class FaceCard( Card ): • """A 10-point face card: J, Q, K.""" • def __init__( self, r, s ):

super(FaceCard,self).__init__( r, s ) • self.pval= 10 • def __str__( self ): • label= ("J","Q","K")[self.rank-11] • return "%2s%s" % ( label, self.suit )

Class Ace

• class Ace( Card ): • """An Ace: either 1 or 11 points.""" • def __str__( self ): • return "%2s%s" % ( "A", self.suit ) • def getHardValue( self ): • return 1 • def getSoftValue( self ): • return 11

Class Hand• class Hand( object ): • """Model a player's hand.""" • def __init__( self ): • self.cards = [ ] • self.softDiff= 0 • def addCard( self, aCard ): • self.cards.append( aCard ) • if aCard.getHardValue() != aCard.getSoftValue(): • if self.softDiff == 0: • self.softDiff= aCard.getSoftValue()-aCard.getHardValue() def points( self ): • """Compute the total points of cards held.""" • p= 0 • for c in self.cards: • p += c.getHardValue() • if p + self.softDiff <= 21: • return p + self.softDiff • else: • return p

Polymorphism

• Polymorphism is the ability to use the same syntax for objects of different types. (Strictly speaking, this is ad-hoc polymorphism.)

• For example, in Python, the square bracket operator is used to perform indexing of various sequence types (list[3], dict["foo"]).

• Polymorphism allows us to define our own types, as classes, that emulate builtin Python types like sequences and which therefore can use e.g. square brackets for indexing.

Polymorphism

• The polymorphism is the process of using an operator or function in different ways for different data input. In practical terms, polymorphism means that if class B inherits from class A, it doesn’t have to inherit everything about class A; it can do some of the things that class A does differently.

Example

• #!/usr/bin/python • # basic.py • a = "alfa" • b = (1, 2, 3, 4) • c = ['o', 'm', 'e', 'g', 'a'] • print a[2] • print b[1] • print c[3]

explained

• Python programming language uses polymorphism extensively in built-in types. Here we use the same indexing operator for three different data types.

• $ ./basic.py • f • 2• g

Polymorphism

• Polymorphism is most commonly used when dealing with inheritance.

Example• #!/usr/bin/python • # polymorphism.py • class Animal: • def __init__(self, name=''):• self.name = name • def talk(self):• pass • class Cat(Animal): • def talk(self): • print "Meow!" • class Dog(Animal): • def talk(self): • print "Woof!" • a = Animal() • a.talk() • c = Cat("Missy") • c.talk() • d = Dog("Rocky") • d.talk()

Explained

• Here we have two species. A dog and a cat. Both are animals. The Dog class and the Cat class inherit the Animal class. They have a talk() method, which gives different output for them.

• $ ./polymorphism.py • Meow! • Woof!

top related