5.1 מחלקות הרצאה
- תכנות מונחה עצמים - object oriented programming (OOP)
למה OOP?¶
- תכנות מונחה עצמים היא גישה תכנותית שמאפשרת לנו לצור תוכנות גדולות יותר בקלות יותר
- תכנות מונחה עצמים הופך את הקוד שלנו לנקי יותר
- תכנות מונחה עצמים זה סנדרט בתעשייה
מה זה OOP?¶
- תכנות מונחה עצמים מאפשר לנו לפתח אובייקטים "מהחיים האמיתיים" בתוך תוכנה.
- אחרי שהגדרנו את ה"אובייקטים" האלו, אנחנו משתמשים בהם בתוכנה שלנו.
- דמיינו שבעצם אנחנו מגדירים בקוד שלנו סוגי משתנים חדשים, ואז פשוט יוצרים אותם ומשתמשים בהם בכל הקוד שלנו. זה עוזר לנו לפשט את הקוד.
- דוגמה לשימוש בסוג משתנה Dog שיצרנו (תכף נראה כיצד אנחנו מגדירים אותו)
- אפשר לראות בדוגמה הזו שיש לנו סוג משתנה בשם "dog" - כלב ואנחנו יכולים להשתמש בו כדי לעשות פעולות של כלב.
- כיצד זה עוזר לנו? אם היינו רוצים לכתוב תוכנת ניהול לכלבים, הסוג משתנה כלב הזה היה יכול מאוד לעזור לנו - הופך את הקוד שלנו לפשוט ומובן יותר.
מחלקה - class¶
- כדי להגדיר סוג משתנה חדש (למשל כלב - dog) נשתמש במילה השמורה class - מחלקה. (בקרוב נסביר איך הקוד הבא עובד)
- בדוגמה הבאה הגדרנו "מחלקה" חדשה: משתנה חדש מסוג כלב, בזכות ההגדרה הזו נוכל ליצור מספר כלבים ולהשתמש בהם בקוד שלנו.
נעבור על כל הפונקציות ונסביר מה הן עושות:
- הפונקציה
__init__ היא פונקציה מיוחדת, היא פונקציה שנקראת אחרי שמשתנה חדש מסוג Dog נוצר (init זה קיצור של initializer או בעברית "מאתחל")- אז מה מטרתה? הפונקציה הזו אחראית ליצור את כל המשתנים הפנימיים של המחלקה.
- שימו לב שכל פונקציה במחלקה מתחילה עם הפרמטר "self", זה בעצם פרמטר מיוחד שמביא לנו גישה לכל הדברים במחלקה, גם
init מקבל כפרמטר ראשון "self".- כאשר אנחנו עושים
self.x = 5, בעצם נוצר משתנה חדש למחלקה שאנחנו מגדירים. אז במקרה שלנו דמיינו שinit מקבל שם של כלב, וגיל, ויוצר 2 משתנים חדשים במחלקה בשם name ו- age.- אז בזכות המתודה
init שהגדרנו לDog, כאשר ננסה ליצור משתנה חדש מסוג Dog, נוכל לתת לו שם וגיל כמו בדרך הבאה:שדות - fields
- שדות הם משתנים של המחלקה
- בדוגמה למטה ניתן לראות איך עם משתנה חדש מסוג כלב אפשר לגשת לשדות של המחלקה
מתודות - methods
- מתודות הן פונקציות של מחלקה, כל פונקציה שאנחנו מגדירים בתוך מחלקה היא נחשבת מתודה.
def bark(self):
print("bark bark")
def eat(self):
print("eating..")
def my_name(self):
self.bark()
print(f"my name is {self.name}")
- שימו לב שכל מתודה מקבלת "self" בהתחלה כפרמטר ראשון, הסברנו קודם שאפשר להשתמש בפרמטר המיוחד הזה כדי ליצור משתנים חדשים במחלקה.
- אנחנו יכולים להשתמש ב"self" גם כדי לגשת למשתנים ולמתודות במחלקה, למשל אפשר לראות שבפונקציה הבאה אנחנו ניגשים גם למתודה וגם שדה של המחלקה.
- אחרי שהגדרנו מתודות למחלקה, אפשר לקרוא להם בחופשיות אחרי שיצרנו משתנים מסוג Dog למשל:
- נקודה חשובה: הפרמטר הראשון לא חייב להיקרא self, יכול להיות לו כל שם, פשוט כקונבציה (מוסכמה) נקרא לו self. - הפרמטר הראשון של מתודה הוא פרמטר מיוחד, לא משנה איך תקראו לו.
ממברים - members
- ממברים הם אוסף של כל השדות והמתודות של מחלקה.
- כל משתנה חדש שנוצר מהמחלקה יהיה לו את כל הממברים של המחלקה.
אובייקט - object
- רגע אז מה הוא אובייקט? אובייקט הוא מופע חדש (משתנה חדש) מסוג המחלקה שהגדרנו, בעצם אפשר להקביל את המילה אובייקט למילה משתנה באופן מסויים.
- כאשר אתם יוצרים משתנים חדשים של מחלקות, קראו להם אובייקטים.
- בעצם אחרי שאנחנו מגדירים מחלקה, אפשר ליצור אובייקטים שלה.
- אפשר לראות באמצעות הפונקציה
type את הסוג של אובייקט מסויים:my_dog = Dog(name="max", age=3) # Creating new Dog
my_dog # Object of type `Dog`
print(type(my_dog)) # Will return "__main__.Dog"
אז מה עושים בOOP?¶
- בOOP אנחנו מגדירים מחלקות, ואז יוצרים אובייקטים ומשתמשים בהם. באמצעות OOP אנחנו יכולים להפוך את הקוד שלנו לברור יותר, כי OOP מאפשר לנו להשתמש בכל סוג של אובייקט שנרצה לצור. אם אנחנו למשל מפתחים משחק מחשב, נוכל לצור אובייקט שמדמה את השחקן של המשחק, את האוייבים, ואת המפה של המשחק - זה יגרום לקוד שלנו להיות יותר ברור ופשוט.
תיעוד למחלקות¶
- כמו לפונקציות ומודולים אפשר לעשות doc-string גם למחלקות.
""" animal.py module is for declaring animals """ class Dog: """ The Dog class represents dog """ def __init__(self, name, age): """ The initializer of dog """ self.name = name self.age = age def bark(self): """ Makes the dog bark """ print("bark bark") def eat(self): """ Makes the dog eat """ print("eating..") def my_name(self): """ Makes the dog tell us his name """ self.bark() print(f"my name is {self.name}") - תמיד תתעדו!
ברירת מחדל לשדות¶
- כמו שאפשר לתת ערך ברירת מחדל לפרמטרים בפונקציות, אפשר גם למחלקות באמצעות השמת פרמטר עם ברירית מחדל לinit: