0% 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.

Uploaded by

dgammer995
Copyright
© © All Rights Reserved
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% 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.

Uploaded by

dgammer995
Copyright
© © All Rights Reserved
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
}

You might also like