راه
۵ کیو· متوسط رو به بالامتوسطPYTHON۴ ثانیه · ۲۵۶ مگابایت

سلسله‌مراتب وراثت وسایل نقلیه

این تمرین در اصل برای ارسال چند فایل جدا (در یک zip) نوشته شده است. در این نسخه همه‌ی کلاس‌ها را در همین یک فایل بنویس — import بین فایل‌ها لازم نیست و کار هم نمی‌کند، و فایل zip هم فرستاده نمی‌شود. کد خودت را بنویس و بفرست.

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

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


📊 تصویر سلسله‌مراتب کلاس‌ها

text
Vehicle
├── GroundVehicle
├── FlyingVehicle
└── Airplane (inherits from GroundVehicle & FlyingVehicle)
      └── B707

کلاس Vehicle

این کلاس ویژگی‌های مشترک همه‌ی وسایل نقلیه را دارد.

سازنده (init)

چهار پارامتر name (نام وسیله)، price (قیمت)، number_of_seats (تعداد صندلی‌ها)، و max_speed (بیشینه‌ی سرعت) را دریافت می‌کند و آن‌ها را در ویژگی‌های متناظر خود در self ذخیره می‌کند.

python
class Vehicle:
    def __init__(self, name, price, number_of_seats, max_speed):
        self.name = name
        self.price = price
        self.number_of_seats = number_of_seats
        self.max_speed = max_speed

کلاس GroundVehicle

این کلاس از کلاس Vehicle ارث می‌برد و ویژگی‌های مختص وسایل نقلیه‌ی زمینی را اضافه می‌کند و از Vehicle ارث‌بری می‌کند.

سازنده (init)

دو پارامتر number_of_wheels (تعداد چرخ‌ها) و steering_wheel (نوع فرمان) را به‌همراه پارامترهای کلاس Vehicle دریافت می‌کند و آن‌ها را در ویژگی‌های متناظر خود در self ذخیره می‌کند.

💡 راهنمایی: دو درس‌نامه‌ی قبل را به یاد بیاورید. سازنده‌ی این کلاس باید با فراخوانی سازنده‌ی کلاس والد (با استفاده از super()) پارامترهای مربوط به Vehicle را به آن ارسال کند و سپس پارامترهای مختص خود را ذخیره کند.

python
class GroundVehicle(Vehicle):
    def __init__(self, number_of_wheels, steering_wheel, **kwargs):
        self.number_of_wheels = number_of_wheels
        self.steering_wheel = steering_wheel
        super().__init__(**kwargs)

کلاس FlyingVehicle

این کلاس از کلاس Vehicle ارث می‌برد و ویژگی‌های مختص وسایل نقلیه‌ی هوایی را اضافه می‌کند و از Vehicle ارث‌بری می‌کند.

سازنده (init)

علاوه‌بر پارامترهای کلاس Vehicle، دو پارامتر fuel (نوع سوخت) و number_of_fins (تعداد پره‌ها یا باله‌ها) را به‌همراه پارامترهای کلاس Vehicle دریافت می‌کند و آن‌ها را در ویژگی‌های متناظر خود در self ذخیره می‌کند.

python
class FlyingVehicle(Vehicle):
    def __init__(self, fuel, number_of_fins, **kwargs):
        self.fuel = fuel
        self.number_of_fins = number_of_fins
        super().__init__(**kwargs)

کلاس Airplane

این کلاس نمایانگر یک هواپیما است و به دلیل ماهیت آن، از هر دو کلاس GroundVehicle و FlyingVehicle ارث‌بری می‌کند (وراثت چندگانه).

سازنده (init)

این سازنده باید پارامترهای مربوط به Vehicle، GroundVehicle، FlyingVehicle و هم‌چنین پارامترهای airline (خط هوایی)، number_of_crew (تعداد خدمه)، و captain (نام کاپیتان) را دریافت می‌کند و آن‌ها را در ویژگی‌های متناظر خود در self ذخیره می‌کند.

کلاس B707

این کلاس یک مدل خاص از هواپیما است و از Airplane ارث‌بری می‌کند.

سازنده (init)

این سازنده باید تمام پارامترهایی را که کلاس Airplane (و در نتیجه تمام کلاس‌های والد آن) نیاز دارند، دریافت کند.

python
class Airplane(GroundVehicle, FlyingVehicle):
    def __init__(self, airline, number_of_crew, captain, **kwargs):
        self.airline = airline
        self.number_of_crew = number_of_crew
        self.captain = captain
        super().__init__(**kwargs)
python
class B707(Airplane):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

💡 چالش‌های حل تمرین

⚠️ ارث‌بری را چگونه انجام دهم؟

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

ترتیب ذکر کلاس‌های والد در تعریف کلاس، بر MRO تأثیر می‌گذارد؛ بنابراین مطابق ترتیب گفته‌شده ارث‌بری را انجام دهید.

⚠️ چگونه از یک کلاس در یک فایل دیگر استفاده کنیم؟

درس‌نامه‌ی بسته‌بندی فایل‌ها را به یاد بیاورید. برای استفاده از کلاس‌هایی که در فایل‌های دیگر تعریف شده‌اند، باید آن‌ها را با استفاده از دستور import وارد کنید.

python
from vehicle import Vehicle

from ground_vehicle import GroundVehicle
from flying_vehicle import FlyingVehicle

⚠️ چگونه ویژگی‌های کلاس پدر را به‌عنوان ورودی در سازنده‌ی فرزند دریافت کنم؟

برای خودداری از بازنویسی نام تمام ویژگی‌ها (که بسیار زیاد هستند) می‌توانید ویژگی‌های اضافه (که باید در کلاس پدر مقداردهی شوند) را با استفاده از **kwargs دریافت کنید و به همین شکل نیز به تابع سازنده‌ی پدر بدهید.

اگر چنین ساختاری را در همه‌ی کلاس‌ها رعایت کنید، در هر مرحله، ویژگی‌های مربوط به آن کلاس از بین ورودی‌ها جدا می‌شوند و بقیه به‌طور خودکار در **kwargs قرار می‌گیرند.

تضمین می‌شود که تمام ورودی‌ها به‌صورت کلید و مقدار به کد شما داده می‌شود.

python
class GroundVehicle(Vehicle):
    def __init__(self, number_of_wheels, steering_wheel, **kwargs):
        ...
        super().__init__(**kwargs)
python
bicycle = GroundVehicle(name="Bicycle", price=100, number_of_seats=1, max_speed=60, number_of_wheels=2, steering_wheel="Manual")

⚠️ چگونه ویژگی‌های کلاس والد را در کلاس فرزند ارث‌بری و سازنده را فراخوانی کنیم؟

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


⚠️ مشکلات متداول

  • در هیچ‌کدام از توابع نباید مقداری را چاپ (print) کنید.
  • اطمینان حاصل کنید که سازنده‌های هر کلاس، تمام پارامترهای موردنیاز برای مقداردهی اولیه‌ی ویژگی‌های خود و ویژگی‌های کلاس‌های والد خود را دریافت می‌کنند و آن‌ها را به‌درستی با استفاده از super() به سازنده‌ی والد ارسال می‌کنند.
  • برای ارسال پاسخ، باید یک فایل زیپ شامل دقیقاً چهار فایل مشخص‌شده را آپلود کنید.
  • به نام دقیق فایل‌ها و کلاس‌ها توجه کنید.

نمونه‌ها

ورودی نمونه ۱
car = Vehicle("Car", 10000, 4, 180)
[car.name, car.price, car.number_of_seats, car.max_speed]
خروجی نمونه ۱
['Car', 10000, 4, 180]
ورودی نمونه ۲
bicycle = GroundVehicle(name="Bicycle", price=100, number_of_seats=1, max_speed=60, number_of_wheels=2, steering_wheel="Manual")
sorted(vars(bicycle).items())
خروجی نمونه ۲
[('max_speed', 60), ('name', 'Bicycle'), ('number_of_seats', 1), ('number_of_wheels', 2), ('price', 100), ('steering_wheel', 'Manual')]
ورودی نمونه ۳
drone = FlyingVehicle(name="Drone", price=500, number_of_seats=0, max_speed=80, fuel="electric", number_of_fins=4)
sorted(vars(drone).items())
خروجی نمونه ۳
[('fuel', 'electric'), ('max_speed', 80), ('name', 'Drone'), ('number_of_fins', 4), ('number_of_seats', 0), ('price', 500)]
ورودی نمونه ۴
plane = B707(name="Boeing 707", price=1000000, number_of_seats=180, max_speed=960,
             number_of_wheels=10, steering_wheel="Yoke", fuel="jet", number_of_fins=2,
             airline="Iran Air", number_of_crew=8, captain="Ahmadi")
sorted(vars(plane).items())
خروجی نمونه ۴
[('airline', 'Iran Air'), ('captain', 'Ahmadi'), ('fuel', 'jet'), ('max_speed', 960), ('name', 'Boeing 707'), ('number_of_crew', 8), ('number_of_fins', 2), ('number_of_seats', 180), ('number_of_wheels', 10), ('price', 1000000), ('steering_wheel', 'Yoke')]
ورودی نمونه ۵
[cls.__name__ for cls in B707.__mro__]
[issubclass(Airplane, GroundVehicle), issubclass(Airplane, FlyingVehicle), issubclass(B707, Vehicle)]
خروجی نمونه ۵
['B707', 'Airplane', 'GroundVehicle', 'FlyingVehicle', 'Vehicle', 'object']
[True, True, True]
ورودی نمونه ۶
[issubclass(GroundVehicle, Vehicle), issubclass(GroundVehicle, FlyingVehicle),
 issubclass(FlyingVehicle, Vehicle), issubclass(FlyingVehicle, GroundVehicle)]
خروجی نمونه ۶
[True, False, True, False]
ورودی نمونه ۷
v = Airplane(name="Airplane", price=500000, number_of_seats=300, max_speed=400, number_of_wheels=10,
             steering_wheel="Manual", fuel="Oil", number_of_fins=2, airline="Quera Air", number_of_crew=65,
             captain="Bagher")
sorted(vars(v).items())
خروجی نمونه ۷
[('airline', 'Quera Air'), ('captain', 'Bagher'), ('fuel', 'Oil'), ('max_speed', 400), ('name', 'Airplane'), ('number_of_crew', 65), ('number_of_fins', 2), ('number_of_seats', 300), ('number_of_wheels', 10), ('price', 500000), ('steering_wheel', 'Manual')]

برای نوشتن پاسخ و دریافت امتیاز، ابتدا وارد حساب شوید.

ورود