The document provides an overview of Object Oriented Programming (OOP) principles, including characteristics, class definitions, inheritance, polymorphism, and encapsulation. It explains the importance of code reusability and demonstrates these concepts through examples involving classes like Physics, Shoes, and banking accounts. Key OOP principles such as inheritance, encapsulation, and polymorphism are illustrated with practical code snippets to enhance understanding.
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0 ratings0% found this document useful (0 votes)
3 views8 pages
Python Object Oriented Programming.ipynb
The document provides an overview of Object Oriented Programming (OOP) principles, including characteristics, class definitions, inheritance, polymorphism, and encapsulation. It explains the importance of code reusability and demonstrates these concepts through examples involving classes like Physics, Shoes, and banking accounts. Key OOP principles such as inheritance, encapsulation, and polymorphism are illustrated with practical code snippets to enhance understanding.
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 8
{
"cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Object Oriented Programming (OOP)\n", "> DRY = Don't Repeat Yourself\n", "\n", "The concept of OOP is built around code reuablility, this way code that has been written is easily used in new projects or usecases without having to write the whole code.\n", "\n", "### OOP Characteristics\n", "\n", "An object has two characteristics\n", "1. Attributes\n", "2. Behaviour\n", "\n", "So a baby object will have\n", "* Attributes - name, age, weight and height\n", "* Behaviour - crying, eating and sleeping\n", "\n", "### Principles of OOP\n", "Object Oriented Programming is built around the following principles\n", "* Inheritance - The process of using code from a super or parent class in child class.\n", "* Encapsulation - Hiding information of certain class or classes from others.\ n", "* Polymorphism - This means one thing having many forms; in OOP it refers to the ability to use a method or function in multiple ways depending on the input data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Class\n", "\n", "A class is a blueprint or template for creating objects. Using a class as a blueprint we can create several instances/objects of the class.\n", "\n", "Create the class using the following syntax:\n", ">class ClassName:\n", "\n", "> class Members\n", "\n", "Attributes and Behaviours can be accessed using dot **.** notation\n", "\n", "__Functions within a class are called methods__" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "980.0" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "class Physics:\n", " \n", " gravity = 9.8\n", " \n", " def potentialEnergy(self, mass, height):\n", " return mass*self.gravity*height\n", "\n", "#ObjectName = ClassName()\n", "phys = Physics() #Creating a phyics object\n", "phys.potentialEnergy(10, 10) #Calling the potentialEnergy method using the dot notation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The **_self_** keyword is used to access attributes at the class level rather than at the local level of a method. Languages like java use the **_this_** keyword. So in this example where we state _m*self.gravity*h_ we are saying pull gravity from the class and multiply it to mass and height" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Another Class Example\n", "\n", "When an object is created a method called the constructor is called, this method is called where you create it or not and it is responsible for __initialising__ the class attributes. This is the **\\_\\_init()\\_\\_** method.\ n", "\n", "So the \\_\\_init\\_\\_ method initializes the attributes of the class and hence can be access in the **_show()_** method via the **_self_** keyword" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Brand: Gafa Sandals Name: Anita size: 17\n" ] } ], "source": [ "class Shoes:\n", " \n", " def __init__(self, brand, owner, size):\n", " self.brand = brand\n", " self.size = size\n", " self.owner = owner\n", "\n", " def show(self):\n", " print(\"Brand: \",self.brand,\" Name: \",self.owner,\" size: \",self.size)\n", "\n", "sandals = Shoes(\"Gafa Sandals\", \"Anita\", 17)\n", "sandals.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Inheritance\n", "\n", "Inheritance is the process of passing attributes from a parent class to a child class, other terms are super class to sub-classes to perform inheritance in python use the following syntax. (Passing the ParentClass as a parameter to the ChildClass)\n", "\n", "class ParentClass:\n", " #Class attributes and methods\n", "\n", "class ChildClass(ParentClass, AnotherParentClass):\n", " #initialize parents class" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Example\n", "\n", "In the example below we take on the banking system which has two types of accounts, both savings and current accounts have similar behaviours they can inherit from a general Accounts class.\n", "\n", "1. They both have balance and amount to with attributes.\n", "2. They also have deposit and withdraw methods.\n", "\n", "So instead of creating all this in both our savings and current classes we can just inherit from a parent class accounts" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class Account:\n", " def __init__(self):\n", " self.balance = 10000\n", " print(\"Account balance is: \",self.balance)\n", " \n", " def deposit(self, amount):\n", " self.balance = amount + self.balance\n", " print(\"Account balance is: \",self.balance)\n", " \n", " def withdraw(self, amount):\n", " self.balance = self.balance - amount\n", " print(\"Account balance is: \",self.balance)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Account balance is: 10000\n", "Account balance is: 8000\n" ] } ], "source": [ "class CurrentAccount(Account):\n", " def __init__(self):\n", " Account.__init__(self)\n", "\n", "current = CurrentAccount()\n", "current.withdraw(2000)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Account balance is: 10000\n", "Amount exceeds withdrawal limit\n" ] } ], "source": [ "class SavingsAccount(Account):\n", " def __init__(self):\n", " Account.__init__(self)\n", " \n", " def savingsWithdraw(self, amount):\n", " if(amount < 1000):\n", " super().withdraw(amount)\n", " else:\n", " print(\"Amount exceeds withdrawal limit\")\n", " \n", " \n", "savings = SavingsAccount()\n", "savings.savingsWithdraw(2000)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "From the above we were able to create two child class **SavingsAccount** and **CurrentAccount** from the parent class **Account**\n", "\n", "We were also able to call the functions of the parent class without writing it in as **current.withdraw(1000)**\n", "\n", "In the SavingsAccount class we created a method savingsWithdraw to handle savings account withdrawal specific tasks in this case withdrawal limit but notice we didn't write the withdrawal logic again we used the **super()** method which the points our code to the parent class and executes the withdraw logic. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Polymorphism\n", "\n", "This is when methods both parent and child class have the same names, there by allowing us to have two separate executions of the methods.\n", "\n", "In the example below our SavingsAccount2 class has **the same method withdraw()** as the parent class.\n", "\n", "When we call the withdraw method from the SavingsAccount2 object via savings.withdraw(), we use the super() keyword to invoke the parent withdraw method without having to change the name of the child class withdraw method" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Account balance is: 10000\n", "Amount exceeds withdrawal limit\n" ] } ], "source": [ "class SavingsAccount2(Account):\n", " #def __init__(self):\n", " # Account.__init__(self)\n", " \n", " def withdraw(self, amount):\n", " if(amount < 1000):\n", " super().withdraw(amount)\n", " else:\n", " print(\"Amount exceeds withdrawal limit\")\n", "\n", "savings = SavingsAccount2()\n", "savings.withdraw(1000)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Encapsulation\n", "\n", "This is process of providing restrictions on data, encapsulated data provides a certain level of privacy/security.\n", "\n", "There are two levels of encapsulation **protected** and **private**. When you declare a class member as \n", "**name=\"John\"**;\n", "**_name = \"James\"** protected\n", "The variable name is a public variable meaning it can be accessed anywhere within the program/project\n", "\n", "Using a single underscore (** \\_ **) we can set our variable to protected meaning it can only be accessed in the same class and it's child classes.\n", "\n", "Using double underscore (** \\_\\_ **) will set our class members to private meaning it can only be accessed **within the class it is declared in** (**NOTE: ** There are ways to by pass this)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Example Protected Encapsulation" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Members of Parent class: \n", "2\n", "2\n" ] } ], "source": [ "class Parent: \n", " def __init__(self): \n", " self._n = 2\n", " \n", "# Child class \n", "class Child(Parent): \n", " \n", " def __init__(self): \n", " \n", " Parent.__init__(self) \n", " print(\"Members of Parent class: \") \n", " print(self._n) \n", " \n", "obj1 = Child() \n", " \n", "obj2 = Parent() \n", "\n", "print(obj2._n) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Example Private Encapsulation" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Variable A\n" ] }, { "ename": "AttributeError", "evalue": "'Parent' object has no attribute '__b'", "output_type": "error", "traceback": [ "\u001b[1;31m-----------------------------------------------------\u001b[0m", "\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m<ipython-input-23-0369ed949916>\u001b[0m in \ u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 18\u001b[0m \ u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 19\u001b[0m \u001b[1;31m#Printing B throws an error\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\ u001b[1;32m---> 20\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\ u001b[0mobj1\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__b\u001b[0m\u001b[1;33m)\ u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mAttributeError\u001b[0m: 'Parent' object has no attribute '__b'" ] } ], "source": [ "class Parent: \n", " def __init__(self): \n", " self.a = \"Variable A\"\n", " self.__b = \"Variable B\"\n", " \n", "# Child class \n", "class Child(Parent): \n", " def __init__(self): \n", " \n", " Parent.__init__(self) \n", " print(\"Members of Parent class: \") \n", " print(self.a)\n", " print(self.__b)\n", "\n", "#child = Child()\n", "obj1 = Parent() \n", "print(obj1.a)\n", "\n", "#Printing B throws an error\n", "print(obj1.__b) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Usecase, activity, class and sequence diagram\n", "# Functional and Non-Functional requirements" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.3" } }, "nbformat": 4, "nbformat_minor": 2 }