3.0 - Inheritance in Python
3.0 - Inheritance in Python
• class YorkshireTerrier(Dog):
• def getDogCoat(self):
• print("The Yorkshire Terrier has a Long Dog
Coat.")
Polymorphism
• As an example, let us have a parent class “Dog” with a method
“getDogCoat” and several child classes that inherit this method:
• lass Dobermann(Dog):
• def getDogCoat(self):
• print("The Dobermann has a Short Dog Coat.")
• class Poodle(Dog):
• def getDogCoat(self):
• print("The Poddle has a Curly Coat.")
Polymorphism
• As an example, let us have a parent class “Dog” with a method
“getDogCoat” and several child classes that inherit this method:
• yk = YorkshireTerrier()
• yk.introduceDog() # Outputs: The dog goes bark.
• yk.getDogCoat() # Outputs: The Yorkshire Terrier has
a Long Dog Coat.
• db = Dobermann()
• db.introduceDog() # Outputs: The dog goes bark.
• db.getDogCoat() # Outputs: The Dobermann has a Short
Dog Coat.
Polymorphism
• As an example, let us have a parent class “Dog” with a method
“getDogCoat” and several child classes that inherit this method:
• p = Poodle()
• p.introduceDog() # Outputs: The dog goes bark.
• p.getDogCoat() # Outputs: The Poddle has a Curly
Coat.
Polymorphism
• As seen in the example, the “getDogCoat()” method is used by
multiple child classes of the “Dog” class.
• Despite the child classes all inheriting the “getDogCoat()”, they
overwrite with their own output.
• This allows the “getDogCoat()” to have different outputs
depending on which child classes implements it.
• Polymorphism makes use of concepts in overriding for it to
work.
Abstract Classes
Object Oriented Programming
Abstract Classes
• Abstract base classes (ABC), defines a set of methods and
properties that a class must implement.
• A class can extend an abstract base class itself in order to be
used as an instance of that class.
• In doing this, the class in question must supply all the
appropriate methods.
Creating Abstract Classes
• The first method of implementing abstract classes is quite
simple, we simply give an error if a class is not changed:
• class Fruit:
• def check_ripeness(self):
• raise NotImplementedError("check_ripeness
method not implemented!")
• class Apple(Fruit):
• pass
Creating Abstract Classes
• When we try to implement the class, we will get an error:
• apple1 = Apple()
• apple1.check_ripeness() # Gives a
"NotImplementedError: check_ripeness method not
implemented!"
• This informs the user or developer to implement the specified
class.
• While this encourages implementation of these classes, it does
not enforce their definition.
Creating Abstract Classes
• We can make use of the “abc” module, to enforce
implementation.
• This prevents child classes from being instantiated if they failed
to override abstract class methods:
• from abc import ABCMeta, abstractmethod
• subclass1 = SubClass()
• subclass1.required_method() # Gives an Error when
Run
NotImplementedError() vs ABC
• You many be wondering why should we go through the trouble
of implementing ABC if both methods give an error.
• In the case of NotImplementedError(), this still allows us to
instantiate an object of an Abstract class without getting an
error.
• We will not get an error until we try to call the abstract
method/s in question.
NotImplementedError() vs ABC
• On the other hand, the ABC module stops us from instantiating
a class completely unless we override the abstract method.
• If we try to instantiate a child class, we will immediately get an
error.
• The error will occur regardless of whether we implement the
abstract methods or not.
Multiple Inheritance
Object Oriented Programming
Multiple Inheritance
• Multiple Inheritance is a case where a subclass that inherits
from multiple parent classes can access functionality from both.
• In practice, this is less useful than it sounds, and it is not
recommended to use this method.
• The simplest and most useful form of multiple inheritance is
called a mixin.
• A mixin is generally a superclass that is not meant to exist on its
own but is meant to be inherited to provide extra functions.
Multiple Inheritance in Diagram
Food
String: name
int: calories
Breakfast_Food beDigested()
Lunch_Food
int: servings
int: protein int: servings
beDigested() beDigested()
Brunch_Food
int: cost
beDigested()
• Breakfast_Food and Lunch_Food
inherit Food
• Brunch_Food inherits both
Breakfast_Food and Lunch_Food
• Output:
name is Food
protein count is 20
serving size is 1
cost is 10
Multiple Inheritance
• Let us say we have a contact list class called “Contacts”:
• class Contact:
• def __init__(self, name, email):
• self.name = name
• self.email = email
• # Other contact information
• def editContactInfo(self):
• # Editing contact information
• def delContactInfo(self):
• # Deleting contact information
Multiple Inheritance
• Next, let’s say we wanted to add some functionality to the
“Contact” class that allows sending an email to “self.email”.
• We can write a mixin class to do the e-mailing:
• class MailSender:
• def send_mail(self, message):
• print("Sending mail to " + self.mail)
• # Email code goes here
• This class doesn’t do anything special, but it allows us to define
a new class that describes both “Contact” and “MailSender”.
Multiple Inheritance
• We can now create a class that makes use of multiple
inheritance:
• class EmailableContact(Contact, MailSender):
• pass
• email = EmailableContact("John Doe",
"[email protected]")
• email.send_mail("Hello, this is a test email!")
Multiple Inheritance
• Just to emphasize that there are better methods to implement
this instead of multiple inheritance, here are some alternatives:
• You can use single inheritance and add the “send_mail” function to the
subclass.
• You can create a standalone Python function for sending an e-mail, and just
call that function with the correct e-email address.