OOP یک مفهوم مهم است که هر توسعه دهنده باید آن را درک کند، به خصوص زمانی که برای مصاحبه های شغلی آماده می شود. این به شما کمک می کند کد را در بخش های ماژولار و قابل استفاده مجدد سازماندهی کنید، که توسعه، نگهداری و مقیاس بندی برنامه های نرم افزاری را ساده می کند.

در این مقاله، من از برخی سوالات رایج مصاحبه برای ساده کردن مفاهیم کلیدی OOP، ارائه توضیحات واضح و تکه کد برای افزایش اعتماد به نفس شما برای مصاحبه بعدی استفاده خواهم کرد.

فهرست مطالب

  • OOP چیست؟

  • چهار اصل اصلی OOP چیست؟

  • روش اضافه بار چیست؟

  • سازنده در OOP چیست؟

  • Destructor در OOP چیست؟

  • کلاس در OOP چیست؟

  • یک شی در OOP چیست؟

  • روش استاتیک چیست؟

  • تفاوت بین متغیر کلاس و متغیر نمونه چیست؟

  • آیا پایتون از وراثت چندگانه پشتیبانی می کند؟

  • تفاوت بین یک کلاس انتزاعی و یک رابط چیست؟

  • نتیجه گیری

OOP چیست؟

برنامه نویسی شی گرا (OOP) روشی برای نوشتن نرم افزار است که حول اشیا می چرخد. این اشیا می توانند داده ها و اقدامات آنها (روش ها) را ذخیره کنند. به جای تمرکز صرف روی فرآیندها و منطق، OOP شما را تشویق می کند تا کد خود را حول این اشیاء ساختار دهید.

این رویکرد ایجاد طرح های نرم افزاری ماژولار، قابل استفاده مجدد و مقیاس پذیر را آسان تر می کند.

چهار اصل اصلی OOP چیست؟

چهار رکن OOP عبارتند از:

  • کپسولاسیون

  • انتزاع

  • ارث

  • چند شکلی

کپسولاسیون چیست و چرا مهم است؟

کپسوله سازی به محافظت از داده های داخل یک شی کمک می کند. به این فکر کنید که جزییات خاصی را خصوصی نگه دارید و فقط به آنها اجازه دسترسی کنترل شده را بدهید.

یعنی به جای اینکه مستقیماً داده ها را تغییر دهید یا مشاهده کنید، از طریق روش های خاص با آنها تعامل دارید. این تضمین می کند که داده ها از تغییرات ناخواسته ایمن هستند.

مثال:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.__age = age  # Private attribute (notice the double underscore)

    def get_age(self):
        return self.__age  # A method to access the private age attribute

در این مثال، __age خصوصی نگه داشته می شود و ما فقط می توانیم سن را با استفاده از get_age() روش این تضمین می کند که age به طور تصادفی به گونه ای اصلاح نشده است که بتواند مشکلاتی ایجاد کند.

Abstraction چیست و چه تفاوتی با کپسولاسیون دارد؟

Abstraction به شما این امکان را می دهد که فقط جزئیات مهم یک شی یا سیستم را نشان دهید، در حالی که قسمت های پیچیده ای را که کاربر نیازی به دیدن آنها ندارد پنهان کنید.

مانند رانندگی با ماشین فکر کنید، فقط باید بدانید که چگونه از فرمان، دنده، پدال گاز و ترمز برای رانندگی استفاده کنید. شما نیازی به درک روش عملکرد موتور داخلی ندارید.

در برنامه نویسی، انتزاع به شما کمک می کند تمرکز کنید روی کاری که چیزی انجام می دهد، نه اینکه چگونه در داخل کار می کند.

مثال: فرض کنید از a استفاده می کنید Car کلاس انتزاع به شما امکان می دهد ماشین را بدون دانستن تمام جزئیات مکانیکی روشن کنید:

class Car:
    def start_engine(self):
        print("Engine started")

    def drive(self):
        print("Car is driving")

# The user interacts with the car without knowing how the engine works
my_car = Car()
my_car.start_engine()
my_car.drive()

در اینجا، لازم نیست نگران روش start_engine روش به صورت داخلی کار می کند، شما فقط از آن استفاده کنید!

تفاوت کلیدی:

  • کپسوله سازی: فوکوس می کند روی بسته بندی داده ها و محدود کردن دسترسی

  • انتزاع: تمرکز می کند روی پنهان کردن پیچیدگی و افشای تنها جزئیات ضروری.

وراثت در OOP چیست؟

وراثت به شما امکان می دهد با استفاده از یک کلاس موجود یک کلاس جدید ایجاد کنید. کلاس جدید (به نام کلاس فرزند) تمام ویژگی ها و متدها را از کلاس موجود (به نام کلاس والد) دریافت می کند.

این به شما امکان می دهد بدون شروع از ابتدا از کدها استفاده مجدد کنید و آنچه را قبلاً نوشته اید بسازید.

مثال:

# Parent class
class Vehicle:
    def __init__(self, brand):
        self.brand = brand  # This is an attribute (brand)

    def start(self):
        print(f"{self.brand} vehicle started")  # This is a method

# Child class that inherits from Vehicle
class Car(Vehicle):
    def __init__(self, brand, model):
        super().__init__(brand)  # Inherit the brand from Vehicle (parent class)
        self.model = model  # Add a new attribute specific to Car

    def display_info(self):
        print(f"Car: {self.brand}, Model: {self.model}")

# Creating an object of the Car class
my_car = Car("IVM", "Ikenga")
my_car.start()  # Output: IVM vehicle started
my_car.display_info()  # Output: Car: IVM, Model: Ikenga

در این مثال، Vehicle کلاس والد است و Car کلاس کودک است Car را به ارث می برد brand و start() روش از Vehicle، اما ویژگی خاص خود را نیز دارد (model) و روش (display_info()).

پیشنهاد می‌کنیم بخوانید:  روش دریافت تاریخ کنونی در جاوا اسکریپت چه در حال ایجاد یک برنامه روتین روزانه، چه وبلاگ خود، یا هر نوع برنامه وب پویا دیگری هستید، احتمالاً باید با تاریخ ها کار کنید. در این مقاله قصد داریم روش دریافت تاریخ جاری در جاوا اسکریپت را بیاموزیم تا بتوانید با موفقیت برنامه های خود را توسعه دهید.

وراثت ایجاد کلاس های تخصصی تر را آسان تر می کند (مانند Car) بر اساس روی یک کلاس عمومی (مانند Vehicle).

پلی مورفیسم چیست؟

چند شکلی به انواع مختلف اشیاء اجازه می دهد تا به یک عمل مشابه به روش منحصر به فرد خود پاسخ دهند. مثل این است که هم گربه ها و هم سگ ها صدا تولید می کنند، اما وقتی از آنها می خواهید هر کدام صدای متفاوتی تولید می کنند!

چندشکلی را می توان از طریق overriding متد به دست آورد (زمانی که یک کلاس فرزند متدی به همان نام متد در کلاس والد خود دارد اما پیاده سازی خود را ارائه می دهد).

مثالی از غلبه بر روش:

# Parent class
class Animal:
    def sound(self):
        return "Some generic animal sound"

# Child class Dog overriding the sound method
class Dog(Animal):
    def sound(self):
        return "Bark"

# Child class Cat overriding the sound method
class Cat(Animal):
    def sound(self):
        return "Meow"

# Creating instances of each class
my_dog = Dog()
my_cat = Cat()

# Calling the sound method
print(my_dog.sound())  # Output: Bark
print(my_cat.sound())  # Output: Meow

در این مثال:

  • Animal کلاس والد است و متدی به نام دارد sound().

  • هر دو Dog و Cat کلاس های کودک از Animal، و آنها را نادیده می گیرند sound() روشی برای ارائه صدای خاص خود.

  • وقتی تماس می گیرید sound() روی یک سگ، “Bark” را برمی گرداند، و برای یک گربه، “Meow” را برمی گرداند.

این چند شکلی در عمل است، اشیاء مختلف (سگ، گربه) به یک روش پاسخ می دهند (sound()) به طرق مختلف

این یک ابزار قدرتمند است که به ایجاد کد انعطاف پذیر و آسان برای نگهداری کمک می کند!

روش اضافه بار چیست؟

بارگذاری متد زمانی اتفاق می‌افتد که چندین متد را با نام یکسان، اما با انواع پارامترهای مختلف در یک کلاس ایجاد کنید.

در حالی که پایتون از بارگذاری بیش از حد متد سنتی پشتیبانی نمی‌کند، می‌توانید با استفاده از آرگومان‌ها/پارامترهای پیش‌فرض یا مدیریت چندین آرگومان در داخل متد، رفتار مشابه را تقلید کنید.

مثال 1: استفاده از پارامترهای پیش فرض

class Calculator:
    def add(self, a, b=0, c=0):
        return a + b + c

# Create an instance of Calculator
calc = Calculator()

# Call the add method with different numbers of arguments
print(calc.add(5))        # Output: 5 (a = 5, b and c default to 0)
print(calc.add(5, 10))    # Output: 15 (a = 5, b = 10, c default to 0)
print(calc.add(5, 10, 15))# Output: 30 (a = 5, b = 10, c = 15)

در این مثال، add روش دارای یک پارامتر مورد نیاز است (a) و دو پارامتر اختیاری (b و c) با مقادیر پیش فرض 0.

با تغییر تعداد آرگومان هایی که هنگام فراخوانی متد ارسال می کنید، می توانید به اثر بارگذاری بیش از حد متد برسید.

مثال 2: استفاده از *args برای پارامترهای دینامیک

class Calculator:
    def add(self, *args):
        return sum(args)

# Create an instance of Calculator
calc = Calculator()

# Call the add method with different numbers of arguments
print(calc.add(5))           # Output: 5 (adds just one number)
print(calc.add(5, 10))       # Output: 15 (adds two numbers)
print(calc.add(5, 10, 15))   # Output: 30 (adds three numbers)

در این مثال، add متد به لطف وجود می تواند هر تعداد آرگومان را مدیریت کند *args، به شما امکان می دهد متد را با یک یا چند پارامتر فراخوانی کنید. تمام اعداد ارسال شده به آن را خلاصه می کند.

سازنده در OOP چیست؟

سازنده یک متد خاص است که هنگام ایجاد یک شی جدید از یک کلاس به طور خودکار اجرا می شود. این به تنظیم مقادیر اولیه شی (مانند تنظیم نام یا سن یک شخص) کمک می کند.

در پایتون، متد سازنده نامگذاری شده است __init__، که مخفف “initialize” است.

مثال:

class Student:
    def __init__(self, name, grade):  # The constructor method
        self.name = name  # Setting the name when the object is created
        self.grade = grade  # Setting the grade when the object is created

# Creating a new Student object
student1 = Student("Alice", "A")

# Accessing the student's details
print(student1.name)  # Output: Alice
print(student1.grade)  # Output: A

در این مثال، __init__ متد به طور خودکار مقادیر را برای name و grade هنگامی که ما ایجاد می کنیم Student شی (مانند student1وقتی شما print student1.name، “آلیس” را نشان می دهد و student1.grade “A” را نشان می دهد.

این به تنظیم هر شی دانش آموز با جزئیات متفاوت در صورت نیاز کمک می کند!

Destructor در OOP چیست؟

Destructor متدی است که هنگام از بین رفتن یک شی فراخوانی می شود. در پایتون، ویرانگر با استفاده از آن تعریف می شود __del__.

مثال:

class Demo:
    def __init__(self):
        print("Constructor called")

    def __del__(self):
        print("Destructor called")

obj = Demo()
del obj  # Explicitly calling the destructor

در این مثال، Demo کلاس یک سازنده دارد (__init__(__del__) که وقتی شیء حذف می شود، “Destructor called” را چاپ می کند.

پیشنهاد می‌کنیم بخوانید:  مقایسه window.onload با document.onload در جاوا اسکریپت

این del obj صراحتاً تخریب کننده را تحریک می کند تا شی را تمیز کند.

کلاس در OOP چیست؟

یک کلاس مانند یک الگو برای ساخت اشیا در برنامه نویسی است. این ویژگی ها (که ویژگی ها نامیده می شوند) و اقدامات (به نام متدها) اشیاء را مشخص می کند. یک کلاس را به عنوان یک دستور غذا در نظر بگیرید که به شما می گوید چگونه چیزی مانند یک ماشین ایجاد کنید.

مثال:

 class Car:
    def __init__(self, make, model):
        self.make = make  # The brand of the car, like IVM
        self.model = model  # The specific model, like Ikenga

    def display_info(self):
        return f"Car: {self.make}, Model: {self.model}"  # Shows the car's information

در این مثال:

  • Car کلاسی است که ماشین را توصیف می کند.

  • make و model ویژگی هایی هستند که اطلاعات مربوط به خودرو را نگه می دارند.

  • display_info روشی است که به ما می گوید چگونه جزئیات ماشین را بدست آوریم.

وقتی یک شی ماشین از این کلاس ایجاد می کنیم، درست مانند ماشین های واقعی، مدل و مدل خاص خود را خواهد داشت!

یک شی در OOP چیست؟

یک شیء مثال خاصی از یک کلاس است. آن را مانند یک آیتم واقعی در نظر بگیرید که دارای ویژگی های خاصی است که توسط کلاس تعریف شده است. هنگامی که یک شی را ایجاد می کنید، به آن مقادیر واقعی برای ویژگی های آن می دهید.

my_car = Car("IVM", "Ikenga")
print(my_car.display_info())  # This will show: Car: IVM, Model: Ikenga

در این مثال، my_car یک شی است که از Car کلاس

روش استاتیک چیست؟

این متدی است که به یک کلاس تعلق دارد، نه به یک نمونه (ابجکت) از آن کلاس. برخلاف روش‌های دیگر، روش‌های استاتیک نیازی به دسترسی به داده‌های خاص نمونه (ویژگی‌ها) یا داده‌های خاص کلاس ندارند.

شما می توانید یک متد استاتیک را مستقیماً از کلاس بدون ایجاد یک شی فراخوانی کنید.

مثال:

class MathOperations:
    @staticmethod  # This tells Python it's a static method
    def add(a, b):
        return a + b

# We don't need to create an object of the class to use the static method
result = MathOperations.add(5, 3)
print(result)  # Output: 8

در این مثال، @staticmethod برای تعریف روش به عنوان استاتیک استفاده می شود. می توانید تماس بگیرید MathOperations.add() مستقیماً با استفاده از نام کلاس، بدون ایجاد شیء از MathOperations.

تفاوت بین متغیر کلاس و متغیر نمونه چیست؟

یک متغیر کلاس در بین تمام نمونه‌های یک کلاس به اشتراک گذاشته می‌شود، در حالی که یک متغیر نمونه مختص هر شی است و در داخل متدها، معمولاً در سازنده، تعریف می‌شود.

مثال:

class MyClass:
    class_var = "I am a class variable"

    def __init__(self, instance_var):
        self.instance_var = instance_var  # Instance variable

در این مثال، یک کلاس MyClass دارای متغیر کلاس است class_var که توسط همه نمونه ها مشترک است و یک متغیر نمونه instance_var که برای هر شیء ایجاد شده از کلاس منحصر به فرد است.

آیا پایتون از وراثت چندگانه پشتیبانی می کند؟

بله، پایتون به ارث بردن چندگانه اجازه می دهد، جایی که یک کلاس می تواند از بیش از یک کلاس والد ارث بری کند.

مثال:

class Parent1:
    def display(self):
        print("Parent1")

class Parent2:
    def display(self):
        print("Parent2")

class Child(Parent1, Parent2):
    pass

child = Child()
child.display()  # Method resolution order determines which display() is called

در این مثال، Child کلاس از هر دو ارث می برد Parent1 و Parent2و با توجه به ترتیب تفکیک روش (MRO)، Child تماس خواهد گرفت Parent1‘s display() روش اول

تفاوت بین یک کلاس انتزاعی و یک رابط چیست؟

کلاس انتزاعی نوع خاصی از کلاس است که نمی توانید از آن شی بسازید. می‌تواند هم متدهای ناقص (به نام متدهای انتزاعی) که هیچ پیاده‌سازی ندارند و هم متدهای کاملاً پیاده‌سازی‌شده که کد دارند داشته باشد.

یک رابط مانند قراردادی است که متدهایی را تعریف می کند که باید توسط هر کلاسی که از آن استفاده می کند پیاده سازی شود. در پایتون، ما از طریق کلاس‌های پایه انتزاعی (ABC) که فقط شامل متدهای انتزاعی هستند، به رابط‌ها دست می‌یابیم. هیچ اجرایی ندارند

مثال ساده برای تشریح مفاهیم:

from abc import ABC, abstractmethod

# Abstract Class
class Animal(ABC):
    @abstractmethod
    def sound(self):
        pass  # This is an abstract method, no implementation

    def sleep(self):
        return "Sleeping..."  # This is a regular method with implementation

# Subclass that implements the abstract method
class Dog(Animal):
    def sound(self):
        return "Bark"  # Implementation of the abstract method

class Cat(Animal):
    def sound(self):
        return "Meow"  # Another implementation of the abstract method

# Using the classes
my_dog = Dog()
print(my_dog.sound())  # Output: Bark
print(my_dog.sleep())  # Output: Sleeping...

my_cat = Cat()
print(my_cat.sound())  # Output: Meow
print(my_cat.sleep())  # Output: Sleeping...

در این مثال، یک کلاس انتزاعی Animal با روش انتزاعی soundو دو زیر کلاس، Dog و Cat، پیاده سازی کنید sound روش، نشان دادن استفاده از کلاس های انتزاعی و جایگزینی روش در پایتون.

نتیجه گیری

درک این اصول OOP برای هر توسعه دهنده ای حیاتی است. این پایه و اساس اکثر زبان های برنامه نویسی مدرن را تشکیل می دهد.

با تسلط بر مفاهیم کلیدی و آماده شدن برای سوالات مصاحبه، نه تنها نرم افزار بهتری خواهید ساخت، بلکه شانس خود را برای به دست آوردن نقش توسعه دهنده بعدی خود نیز افزایش خواهید داد.

اگر این راهنما برای شما مفید بود، لطفاً آن را لایک کنید. شما می توانید من را دنبال کنید روی X برای مقالات روشنگرتر.