یکی از مباحث مهم برنامه نویسی، شی گرایی است که هر برنامهنویس حرفهای باید آن را بیاموزد. زبان برنامه نویسی پایتون یکی از زبانهای پایه شی گرا است. به طوری که تمامی دادهها در آن یک شی هستند. در این مقاله با مباحث مختلف برنامه نویسی شی گرا در پایتون از جمله کلاس، شی، ارث بری، کپسوله سازی و غیره آشنا خواهید شد. اگر علاقهمند به یادگیری این موضوعات هستید در ادامه با ما همراه باشید.
برنامه نویسی شی گرا (Object-Oriented Programming) که به صورت مختصر OOP نامیده میشود، یک نوع شیوهی برنامه نویسی کامپیوتری است که در آن طراحی نرم افزار به جای توابع و منطق، حول محور اشیاء و دادهها میچرخد.
برنامه نویسی شی گرا، کدنویسی را در پروژههای بزرگ بسیار آسانتر و خواناتر کرده و کدها منظمتر خواهند بود. پایتون نیز یکی از زبانهای شی گرا است که از اساس به صورت شی نوشته شده است. در این زبان هر متغیر و دادهای که تعریف میکنیم، یک شی است.
در ادامه خواهید دید چگونه در پایتون یک برنامه به صورت شی گرا نوشته میشود.
در برنامه نویسی شی گرا، کلاسها مجموعهای از اشیاء را تعریف میکنند که میتوانند با هم تعامل کنند. در واقع کلاسها سازوکاری برای برنامهنویس جهت دستهبندی و گروهبندی اشیاء مشابه هستند.
تعریف کلاس:
در پایتون، برای تعریف کلاس از کلمهی کلیدی class استفاده میکنند و در ادامه نام کلاس به آن اختصاص داده میشود.
نحوه نوشتاری (Syntax) یک کلاس:
Class Definition Syntax:
class ClassName:
# Statement-1
.
.
.
# Statement-N
مثال:
# Python program to
# demonstrate defining
# a class
class Dog:
pass
نکته: مرسوم است در نام گذاری یک کلاس، حرف اول نام کلاس را با حروف بزرگ بنویسند. پس سعی کنید این نکته را به خاطر داشته باشید و رعایت کنید.
اشیاء در برنامه نویسی شی گرا، از سه قسمت تشکیل شدهاند:
حالت (state): صفتهای یک شی میتوانند مقدار گرفته و خصوصیات یک شی را نشان دهند.
رفتار (Behavior): در اصل کارهایی که یک شی میتواند انجام دهد در متدهای شی قرار میدهند.
هویت (Identity): یک نام منحصر به فرد به شی میدهد و اجازه میدهد یک شی با دیگر اشیاء تعامل داشته باشد.
بیشتر بخوانید: دانلود pycharm : آموزش نرم افزار پایچارم ( نصب و فعالسازی )
برای ایجاد یک شی (object) در پایتون، کافی است نام شی مورد نظر را نوشته و نام کلاس مورد نظر را به آن اختصاص دهیم. در مثال زیر یک کلاس تعریف کرده و در انتها یک شی یا یک نمونه از آن کلاس ایجاد میکنیم.
# Python program to
# demonstrate instantiating
# a class
class Dog:
# A simple class
# attribute
attr1 = "mamal"
attr2 = "dog"
# A sample method
def fun(self):
print("I'm a", self.attr1)
print("I'm a", self.attr2)
# Driver code
# Object instantiation
Rodger = Dog()
# Accessing class attributes
# and method through objects
print(Rodger.attr1)
Rodger.fun()
mamal I'm a mamal I'm a dog
تمامی توابعی که در کلاس تعریف میشوند، متد (Method) نامیده میشوند. یکی از این متدها که سازندهی کلاس نیز محسوب میشود، متد __init__ است. مقداردهی اولیه شی و نیز دستورالعملهایی که در زمان ایجاد شی باید اجرا شود، به وسیلهی این متد انجام میپذیرد.
# A Sample class with init method
class Person:
# init method or constructor
def __init__(self, name):
self.name = name
# Sample Method
def say_hi(self):
print('Hello, my name is', self.name)
p = Person('Nikhil')
p.say_hi()
Hello, my name is Nikhil
در پایتون، برای متدهای کلاس باید یک پارامتر اول اضافی تعریف کرد که موقع فراخوانی، مقداری از سوی ما نمیگیرد و خود پایتون آن را میشناسد.
اگر متد ما هیچ آرگومانی نداشته باشد، باز هم نوشتن پارامتر self الزامی است.
متغیرهای نمونه (Instance Variables): این نوع متغیرها مختص نمونهی ایجاد شده از کلاس هستند و در متد سازنده یا سایر متدهای کلاس تعریف میشوند. هر شی متغیر نمونهی مخصوص خود دارد.
متغیرهای کلاس (class Variables): این نوع متغیر در بدنهی کلاس تعریف شده و در تمامی شیهای ایجاد شده از این کلاس، مشترک است. از این متغیرها به ندرت استفاده میشود.
تعریف متغیر نمونه توسط متد سازنده کلاس:
# Python program to show that the variables with a value
# assigned in the class declaration, are class variables and
# variables inside methods and constructors are instance
# variables.
# Class for Dog
class Dog:
# Class Variable
animal = 'dog'
# The init method or constructor
def __init__(self, breed, color):
# Instance Variable
self.breed = breed
self.color = color
# Objects of Dog class
Rodger = Dog("Pug", "brown")
Buzo = Dog("Bulldog", "black")
print('Rodger details:')
print('Rodger is a', Rodger.animal)
print('Breed: ', Rodger.breed)
print('Color: ', Rodger.color)
print('\nBuzo details:')
print('Buzo is a', Buzo.animal)
print('Breed: ', Buzo.breed)
print('Color: ', Buzo.color)
# Class variables can be accessed using class
# name also
print("\nAccessing class variable using class name")
print(Dog.animal)
Rodger details: Rodger is a dog Breed: Pug Color: brown Buzo details: Buzo is a dog Breed: Bulldog Color: black Accessing class variable using class name dog
تعریف متغیر نمونه در سایر متد کلاس:
# Python program to show that we can create
# instance variables inside methods
# Class for Dog
class Dog:
# Class Variable
animal = 'dog'
# The init method or constructor
def __init__(self, breed):
# Instance Variable
self.breed = breed
# Adds an instance variable
def setColor(self, color):
self.color = color
# Retrieves instance variable
def getColor(self):
return self.color
# Driver Code
Rodger = Dog("pug")
Rodger.setColor("brown")
print(Rodger.getColor())
brown
وراثت یا ارثبری در شی گرایی، امکانی هست که یک کلاس میتواند خصوصیات یک کلاس دیگر را به ارث ببرد و علاوه بر آن خصوصیات دیگری نیز داشته باشد. بعضی از مزایای ارثبری:
قابلیت استفادهی مجدد از کد را مهیا کرده و از تکرار کدهای مشابه جلوگیری میکند و به ما امکان میدهد بدون تغییر کلاس، ویژگیهای جدیدی به آن اضافه کنیم.
ماهیت آن انتقالی است، به این معنی که اگر کلاس B از کلاس A ارث میبرد پس تمام زیر کلاسهای B نیز از کلاس A ارث میبرند.
در زیر یک مثال ساده از ارثبری آورده شده است.
# A Python program to demonstrate inheritance
# Base or Super class. Note object in bracket.
# (Generally, object is made ancestor of all classes)
# In Python 3.x "class Person" is
# equivalent to "class Person(object)"
class Person(object):
# Constructor
def __init__(self, name):
self.name = name
# To get name
def getName(self):
return self.name
# To check if this person is an employee
def isEmployee(self):
return False
# Inherited or Subclass (Note Person in bracket)
class Employee(Person):
# Here we return true
def isEmployee(self):
return True
# Driver code
emp = Person("Geek1") # An Object of Person
print(emp.getName(), emp.isEmployee())
emp = Employee("Geek2") # An Object of Employee
print(emp.getName(), emp.isEmployee())
Geek1 False Geek2 True
در پایتون نسخهی 3، مانند object class جاوا، object ریشهی همه کلاسها است.
در پایتون 3، "(class Test(object" و " class Test" یکسان هستند.
در پایتون 2، "(class Test(object" یک کلاس با object به عنوان پدر ایجاد میکند (کلاس سبک جدید نامیده میشود) و "class Test" کلاس سبک قدیمی (بدون پدر) ایجاد میکند. برای کسب اطلاعات بیشتر مستندات پایتون را مطالعه کنید.
یک کلاس فرزند باید کلاس پدر را مشخص کند، این کار را میتوان با ذکر نام کلاس پدر در تعریف کلاس فرزند انجام داد. به عنوان مثال:
class subclass_name (superclass_name):
_ _ _
_ _ _
برای بهتر فهمیدن کلاس پدر و فرزند در شی گرایی پایتون، به مثال زیر توجه کنید.
# Python code to demonstrate how parent constructors
# are called.
# parent class
class Person( object ):
# __init__ is known as the constructor
def __init__(self, name, idnumber):
self.name = name
self.idnumber = idnumber
def display(self):
print(self.name)
print(self.idnumber)
# child class
class Employee( Person ):
def __init__(self, name, idnumber, salary, post):
self.salary = salary
self.post = post
# invoking the __init__ of the parent class
Person.__init__(self, name, idnumber)
# creation of an object variable or an instance
a = Employee('Rahul', 886012, 200000, "Intern")
# calling a function of the class Person using its instance
a.display()
Rahul 886012
در اینجا کلاس Employee کلاس فرزند و کلاس Person کلاس پدر است و هر آنچه در متد __init__ کلاس پدر است به فرزند ارث میرسد و به همین جهت، فراخوانی نام متغیرهای نمونهی کلاس پدر در متد سازنده کلاس فرزند کافی است. اما اگر به هر دلیلی فراموش کنید نام متغیرهای کلاس پدر را در کلاس فرزند فراخوانی کنید، متغیرهای نمونهی آن در دسترس کلاس فرزند نیستند. کد زیر به همین علت خطایی ایجاد میکند:
# Python program to demonstrate error if we
# forget to invoke __init__() of the parent.
class A:
def __init__(self, n = 'Rahul'):
self.name = n
class B(A):
def __init__(self, roll):
self.roll = roll
object = B(23)
print (object.name)
Traceback (most recent call last): File "/home/de4570cca20263ac2c4149f435dba22c.py", line 12, in print (object.name) AttributeError: 'B' object has no attribute 'name'
وراثت منفرد (Single inheritance): وقتی کلاس فرزند، فقط از یک کلاس پدر ارث ببرد، به آن وراثت منفرد میگویند. در بالا مثالهایی ذکر شد.
وراثت چندگانه (Multiple inheritance): وقتی کلاس فرزند از کلاسهای پدر متعدد ارثبری کند به آن وراثت چندگانه میگویند.
برخلاف سایر زبانهای برنامه نویسی مانند جاوا و سیپلاسپلاس، پایتون از وراثت چندگانه (Multiple inheritance) پشتیبانی میکند.
# Python example to show the working of multiple
# inheritance
class Base1(object):
def __init__(self):
self.str1 = "Geek1"
print("Base1")
class Base2(object):
def __init__(self):
self.str2 = "Geek2"
print("Base2")
class Derived(Base1, Base2):
def __init__(self):
# Calling constructors of Base1
# and Base2 classes
Base1.__init__(self)
Base2.__init__(self)
print("Derived")
def printStrs(self):
print(self.str1, self.str2)
ob = Derived()
ob.printStrs()
Base1 Base2 Derived Geek1 Geek2
وراثت چند سطحی (Multilevel inheritance): این نوع وراثت به زمانی مربوط میشود که رابطه فرزند و نوه داریم. به عنوان مثال:
# A Python program to demonstrate inheritance
# Base or Super class. Note object in bracket.
# (Generally, object is made ancestor of all classes)
# In Python 3.x "class Person" is
# equivalent to "class Person(object)"
class Base(object):
# Constructor
def __init__(self, name):
self.name = name
# To get name
def getName(self):
return self.name
# Inherited or Sub class (Note Person in bracket)
class Child(Base):
# Constructor
def __init__(self, name, age):
Base.__init__(self, name)
self.age = age
# To get name
def getAge(self):
return self.age
# Inherited or Sub class (Note Person in bracket)
class GrandChild(Child):
# Constructor
def __init__(self, name, age, address):
Child.__init__(self, name, age)
self.address = address
# To get address
def getAddress(self):
return self.address
# Driver code
g = GrandChild("Geek1", 23, "Noida")
print(g.getName(), g.getAge(), g.getAddress())
Geek1 23 Noida
وراثت سلسله مراتبی (Hierarchical Inheritance): وقتی بیش از یک کلاس از کلاس پدر ارثبری کنند را وراثت سلسله مراتبی میگویند.
وراثت ترکیبی (Hybrid Inheritance): ارثبری تشکیل شده از انواع وراثت، را وراثت ترکیبی گویند.
گاهی لازم است که بعضی از متغیرهای نمونهی کلاس پدر در دسترس کلاس فرزند نباشد، از این رو با خصوصی (Private) کردن، آن متغیرها را از دسترس کلاس فرزند خارج میکنیم. برای این کار با گذاشتن دو زیر خط قبل از نام متغیر، آنها را خصوصی میکنیم. به عنوان مثال:
# Python program to demonstrate private members
# of the parent class
class C(object):
def __init__(self):
self.c = 21
# d is private instance variable
self.__d = 42
class D(C):
def __init__(self):
self.e = 84
C.__init__(self)
object1 = D()
# produces an error as d is private instance variable
print(object1.d)
File "/home/993bb61c3e76cda5bb67bd9ea05956a1.py", line 16, in print (object1.d) AttributeError: type object 'D' has no attribute 'd'
از آنجایی که متغیر d با دو زیر خط خصوصی شده است، برای کلاس فرزند در دسترس نیست لذا این خطا رخ میدهد.
یکی از مفاهیم بنیادی برنامه نویسی شی گرا، کپسوله سازی است. ایدهی کپسوله سازی از بستهبندی دادهها و متدهایی که در داخل یک واحد کار میکنند، به وجود آمده است. این کار کمک میکند تا دسترسی مستقیم به متغیرها و متدها محدود شده و از تغییر تصادفی دادهها جلوگیری شود. در این روش، تغییر متغیر یک شی فقط با متد همان شی امکانپذیر است. این نوع متغیرها به عنوان متغیر خصوصی شناخته میشود.
یک کلاس، نمونهای از کپسوله سازی است، زیرا تمامی دادههای توابع عضو، متغیرها و غیره را در خود قرار داده است.
اعضای محافظت شده (در زبان ++C و Java) آن دسته از اعضای کلاس هستند که خارج از کلاس قابل دسترسی نیستند، اما از داخل کلاس و زیرکلاسهای آن قابل دسترسی هستند. برای رسیدن به این مقصود در پایتون، باید قبل از نام عضو یک خط زیر "_" گذاشت.
توجه: متد "__init__" یک متد سازنده است و به محض ایجاد یک شی، اجرا میشود.
# Python program to
# demonstrate protected members
# Creating a base class
class Base:
def __init__(self):
# Protected member
self._a = 2
# Creating a derived class
class Derived(Base):
def __init__(self):
# Calling constructor of
# Base class
Base.__init__(self)
print("Calling protected member of base class: ")
print(self._a)
obj1 = Derived()
obj2 = Base()
# Calling protected member
# Outside class will result in
# AttributeError
print(obj2.a)
Calling protected member of base class: 2 Traceback (most recent call last): File "/home/6fb1b95dfba0e198298f9dd02469eb4a.py", line 25, in print(obj1.a) AttributeError: 'Base' object has no attribute 'a'
اعضای خصوصی مشابه اعضای محافظت شده هستند با این تفاوت که اعضای خصوصی فقط داخل خود کلاس قابل دسترسیاند و در خارج از کلاس و هیچ کلاس پایهی دیگری قابل دسترسی نیستند. در پایتون، برای تعریف یک متغیر خصوصی از پیشوند دو خط زیر "__" قبل از نام متغیر استفاده میکنند.
# Python program to
# demonstrate private members
# Creating a Base class
class Base:
def __init__(self):
self.a = "7Lean.com"
self.__c = "7learn.com"
# Creating a derived class
class Derived(Base):
def __init__(self):
# Calling constructor of
# Base class
Base.__init__(self)
print("Calling private member of base class: ")
print(self.__c)
# Driver code
obj1 = Base()
print(obj1.a)
# Uncommenting print(obj1.c) will
# raise an AttributeError
# Uncommenting obj2 = Derived() will
# also raise an AtrributeError as
# private member of base class
# is called inside derived class
7learn.com Traceback (most recent call last): File "/home/f4905b43bfcf29567e360c709d3c52bd.py", line 25, in <module> print(obj1.c) AttributeError: 'Base' object has no attribute 'c' Traceback (most recent call last): File "/home/4d97a4efe3ea68e55f48f1e7c7ed39cf.py", line 27, in <module> obj2 = Derived() File "/home/4d97a4efe3ea68e55f48f1e7c7ed39cf.py", line 20, in __init__ print(self.__c) AttributeError: 'Derived' object has no attribute '_Derived__c'
کلمه چندریختی به معنی داشتن شکلهای مختلف است. در برنامه نویسی هم چندریختی قابلیتی است که شی میتواند شکلهای مختلفی به خود بگیرد.
مثالی از توابع چندریختی ساخته شده:
# Python program to demonstrate in-built poly-
# morphic functions
# len() being used for a string
print(len("7learn"))
# len() being used for a list
print(len([10, 20, 30]))
6 3
مثالی از توابع چندریختی تعریف شده:
# A simple Python function to demonstrate
# Polymorphism
def add(x, y, z = 0):
return x + y+z
# Driver code
print(add(2, 3))
print(add(2, 3, 4))
5 9
در کد زیر میببینید که، پایتون چگونه میتواند از دو نوع کلاس متفاوت به همان شیوه استفاده کند. ما یک حلقهی تکرار for ایجاد میکنیم که از طریق یک تاپل (Tuple) از اشیاء تکرار میشود. سپس بدون نگرانی از نوع کلاس هر شی، متدها را فراخوانی میکنیم. ما فرض میکنیم این متدها در هر کلاس وجود دارد.
class India():
def capital(self):
print("New Delhi is the capital of India.")
def language(self):
print("Hindi is the most widely spoken language of India.")
def type(self):
print("India is a developing country.")
class USA():
def capital(self):
print("Washington, D.C. is the capital of USA.")
def language(self):
print("English is the primary language of USA.")
def type(self):
print("USA is a developed country.")
obj_ind = India()
obj_usa = USA()
for country in (obj_ind, obj_usa):
country.capital()
country.language()
country.type()
New Delhi is the capital of India. Hindi is the most widely spoken language of India. India is a developing country. Washington, D.C. is the capital of USA. English is the primary language of USA. USA is a developed country.
در مقاله آموزش کامل برنامه نویسی شی گرایی در زبان پایتون، شما با کاربرد و مفهوم شی گرایی در پایتون، آشنا شدید. دربارهی متدها و متد سازنده در پایتون توضیح دادیم و همچنین با متغیرهای نمونه و خصوصی در پایتون آشنا شدید. درمورد کپسوله سازی و وراثت توضیحاتی دادیم و در کل مبحث شی گرایی را در حد مقدماتی برای شما آموزش دادیم و شما دانستید شی گرایی در پایتون چیست. مباحث مربوط به شی گرایی در پایتون، بسیار گستردهتر و خارج از حوصلهی این مقاله است. بعضی از موضوعات گفته نشد یا در حد کوتاهی توضیح داده شد که باز به همان محدویت مقاله باز میگردد. اگر علاقهمند به برنامه نویسی و بحثهای پیشرفتهی برنامه نویسی از جمله شی گرایی هستید، نظر خود را در مورد برنامه نویسی شی گرا بنویسید.
اگر به یادگیری بیشتر در زمینهی برنامه نویسی پایتون علاقه داری، یادگیری زبان پایتون بسیار ساده است. و با شرکت در دورهی متخصص پایتون توسعه وب در آینده میتونی اپلیکیشن موبایل و دسکتاپ بسازی و وارد حوزهی هوش مصنوعی هم شوی.
سلام. مبحث آموزش شی گرایی در پایتون مربوط به دوره <a href="https://7learn.com/course/python-web-expert" rel="noopener" target="_blank">آموزش پایتون</a> وب هست و سر فصل آن در دست تهیه است. شما میتونید از صفحه دوره بررسی کنید.
دوره الفبای برنامه نویسی با هدف انتخاب زبان برنامه نویسی مناسب برای شما و پاسخگویی به سوالات متداول در شروع یادگیری موقتا رایگان شد: