برنامهنویسی شیءگرا (OOP) 🏗️🎯
وقتشه کدهامون رو مثل دنیای واقعی سازماندهی کنیم!
🎯 برنامهنویسی شیءگرا چیست؟
برنامهنویسی شیءگرا (Object-Oriented Programming) یک روش برنامهنویسی است که به ما کمک میکند کدهایمان را مثل دنیای واقعی سازماندهی کنیم. تصور کنید میخواهید یک بازی کامپیوتری بسازید - در این بازی شخصیتها، اشیاء، و محیطهای مختلفی وجود دارد. هر کدام از اینها ویژگیها و رفتارهای خاص خودشان را دارند.
🔑 چهار اصل اساسی OOP:
- کپسولهسازی (Encapsulation): مخفی کردن جزئیات داخلی
- وراثت (Inheritance): به ارث بردن ویژگیها از کلاس والد
- چندریختی (Polymorphism): یک رابط، رفتارهای مختلف
- انتزاع (Abstraction): سادهسازی پیچیدگیها
🏗️ کلاس و شیء چیست؟
کلاس (Class) مثل یک نقشه یا قالب است که مشخص میکند یک شیء چه ویژگیها و رفتارهایی دارد. شیء (Object) نمونهای از آن کلاس است که در حافظه ساخته میشود.
🌟 مثال از زندگی واقعی:
کلاس "خودرو" مثل نقشهای است که مشخص میکند هر خودرویی باید برند، مدل، رنگ داشته باشد و بتواند روشن/خاموش شود. "پراید آبی من" یک شیء از این کلاس است!
📝 ساختار کلی یک کلاس:
public class ClassName
{
// فیلدها (Fields) - متغیرهای داخلی کلاس
private int _privateField;
// ویژگیها (Properties) - دسترسی کنترل شده به دادهها
public string PropertyName { get; set; }
// سازنده (Constructor) - برای مقداردهی اولیه
public ClassName(parameters)
{
// مقداردهی اولیه
}
// متدها (Methods) - رفتارهای کلاس
public void MethodName()
{
// کدهای متد
}
}
🚗 مثال عملی: کلاس خودرو
using System;
// تعریف کلاس خودرو
public class Car
{
// فیلدهای خصوصی (Private Fields)
private string _engineType;
private bool _isRunning;
// ویژگیهای عمومی (Public Properties)
public string Brand { get; set; }
public string Model { get; set; }
public int Year { get; set; }
public string Color { get; set; }
public int Mileage { get; private set; } // فقط خواندنی از بیرون
// سازنده (Constructor)
public Car(string brand, string model, int year, string color, string engineType)
{
Brand = brand;
Model = model;
Year = year;
Color = color;
_engineType = engineType;
_isRunning = false;
Mileage = 0;
Console.WriteLine($"خودروی {Brand} {Model} ساخته شد! 🚗");
}
// متدهای عمومی (Public Methods)
public void Start()
{
if (!_isRunning)
{
_isRunning = true;
Console.WriteLine($"{Brand} {Model} با موتور {_engineType} روشن شد! 🔥");
}
else
{
Console.WriteLine("خودرو از قبل روشن است!");
}
}
public void Stop()
{
if (_isRunning)
{
_isRunning = false;
Console.WriteLine($"{Brand} {Model} خاموش شد! 🛑");
}
else
{
Console.WriteLine("خودرو از قبل خاموش است!");
}
}
public void Drive(int distance)
{
if (_isRunning)
{
Mileage += distance;
Console.WriteLine($"{distance} کیلومتر رانندگی کردید. کل کیلومتر: {Mileage}");
}
else
{
Console.WriteLine("ابتدا خودرو را روشن کنید!");
}
}
// متد برای نمایش اطلاعات
public void DisplayInfo()
{
Console.WriteLine($"\n--- اطلاعات خودرو ---");
Console.WriteLine($"برند: {Brand}");
Console.WriteLine($"مدل: {Model}");
Console.WriteLine($"سال: {Year}");
Console.WriteLine($"رنگ: {Color}");
Console.WriteLine($"کیلومتر: {Mileage}");
Console.WriteLine($"وضعیت: {(_isRunning ? "روشن" : "خاموش")}");
Console.WriteLine($"نوع موتور: {_engineType}");
}
}
class Program
{
static void Main()
{
// ساخت اشیاء مختلف از کلاس خودرو
Car car1 = new Car("تویوتا", "کمری", 2023, "سفید", "هیبریدی");
Car car2 = new Car("بنز", "C200", 2024, "مشکی", "توربو");
Console.WriteLine("\n=== تست خودروی اول ===");
car1.DisplayInfo();
car1.Start();
car1.Drive(50);
car1.Drive(30);
car1.Stop();
Console.WriteLine("\n=== تست خودروی دوم ===");
car2.DisplayInfo();
car2.Drive(20); // خطا: خودرو روشن نیست
car2.Start();
car2.Drive(20);
Console.WriteLine("\n=== اطلاعات نهایی ===");
car1.DisplayInfo();
car2.DisplayInfo();
Console.ReadKey();
}
}
🔍 تحلیل کد:
- فیلدهای خصوصی: `_engineType` و `_isRunning` از بیرون قابل دسترسی نیستند
- Properties: `Brand`, `Model` قابل خواندن و نوشتن، `Mileage` فقط خواندنی
- Constructor: مقادیر اولیه را تنظیم میکند
- Methods: رفتارهای مختلف خودرو را پیادهسازی میکنند
- Encapsulation: دادههای حساس محافظت شدهاند
🔒 کپسولهسازی (Encapsulation)
کپسولهسازی یعنی مخفی کردن جزئیات داخلی کلاس و فقط اجازه دسترسی کنترل شده به آنها. مثل یک خانه که درب و پنجره دارد اما اتاقهای خصوصی آن قابل دسترسی نیست.
🔑 سطوح دسترسی در C#:
- public: از همه جا قابل دسترسی
- private: فقط داخل همان کلاس
- protected: داخل کلاس و کلاسهای فرزند
- internal: داخل همان Assembly
using System;
public class BankAccount
{
// فیلدهای خصوصی - از بیرون قابل دسترسی نیستند
private decimal _balance;
private string _accountNumber;
private string _pin;
// ویژگیهای عمومی با کنترل دسترسی
public string AccountHolder { get; private set; }
public decimal Balance
{
get { return _balance; } // فقط خواندنی از بیرون
}
// سازنده
public BankAccount(string accountHolder, string accountNumber, string pin)
{
AccountHolder = accountHolder;
_accountNumber = accountNumber;
_pin = pin;
_balance = 0;
Console.WriteLine($"حساب بانکی برای {AccountHolder} ایجاد شد.");
}
// متد عمومی برای واریز
public void Deposit(decimal amount)
{
if (amount > 0)
{
_balance += amount;
Console.WriteLine($"{amount:C} واریز شد. موجودی: {_balance:C}");
}
else
{
Console.WriteLine("مبلغ واریز باید مثبت باشد!");
}
}
// متد عمومی برای برداشت با احراز هویت
public bool Withdraw(decimal amount, string pin)
{
if (!ValidatePin(pin))
{
Console.WriteLine("رمز عبور اشتباه است!");
return false;
}
if (amount <= 0)
{
Console.WriteLine("مبلغ برداشت باید مثبت باشد!");
return false;
}
if (amount > _balance)
{
Console.WriteLine("موجودی کافی نیست!");
return false;
}
_balance -= amount;
Console.WriteLine($"{amount:C} برداشت شد. موجودی: {_balance:C}");
return true;
}
// متد خصوصی برای احراز هویت
private bool ValidatePin(string pin)
{
return _pin == pin;
}
// متد عمومی برای نمایش اطلاعات (بدون اطلاعات حساس)
public void DisplayAccountInfo()
{
Console.WriteLine($"\n--- اطلاعات حساب ---");
Console.WriteLine($"صاحب حساب: {AccountHolder}");
Console.WriteLine($"شماره حساب: {_accountNumber.Substring(0, 4)}****");
Console.WriteLine($"موجودی: {_balance:C}");
}
}
class Program
{
static void Main()
{
BankAccount account = new BankAccount("احمد محمدی", "1234567890", "1234");
// تست عملیات
account.Deposit(1000000);
account.Withdraw(200000, "1234"); // رمز درست
account.Withdraw(100000, "5678"); // رمز غلط
account.DisplayAccountInfo();
// تلاش برای دسترسی مستقیم به فیلدهای خصوصی (خطا میدهد)
// account._balance = 999999; // کامپایل نمیشود!
// account._pin = "0000"; // کامپایل نمیشود!
Console.ReadKey();
}
}
🧬 وراثت (Inheritance)
وراثت به ما اجازه میدهد کلاس جدیدی بسازیم که ویژگیها و رفتارهای کلاس دیگری را به ارث ببرد. مثل اینکه فرزندان ویژگیهایی از والدین خود به ارث میبرند.
🌳 مزایای وراثت:
- کاهش تکرار کد: کدهای مشترک در کلاس والد نوشته میشود
- سازماندهی بهتر: ساختار سلسله مراتبی منطقی
- قابلیت توسعه: اضافه کردن ویژگیهای جدید به راحتی
- چندریختی: امکان استفاده یکسان از اشیاء مختلف
using System;
// کلاس پایه (Base Class)
public class Vehicle
{
// فیلدهای محافظت شده - قابل دسترسی در کلاسهای فرزند
protected string _engine;
protected bool _isRunning;
// ویژگیهای عمومی
public string Brand { get; set; }
public string Model { get; set; }
public int Year { get; set; }
public int MaxSpeed { get; protected set; }
// سازنده کلاس پایه
public Vehicle(string brand, string model, int year, string engine, int maxSpeed)
{
Brand = brand;
Model = model;
Year = year;
_engine = engine;
MaxSpeed = maxSpeed;
_isRunning = false;
Console.WriteLine($"وسیله نقلیه {Brand} {Model} ساخته شد.");
}
// متد مجازی - قابل بازنویسی در کلاسهای فرزند
public virtual void Start()
{
if (!_isRunning)
{
_isRunning = true;
Console.WriteLine($"{Brand} {Model} با موتور {_engine} روشن شد!");
}
}
public virtual void Stop()
{
if (_isRunning)
{
_isRunning = false;
Console.WriteLine($"{Brand} {Model} خاموش شد!");
}
}
// متد عمومی مشترک
public void DisplayBasicInfo()
{
Console.WriteLine($"برند: {Brand}, مدل: {Model}, سال: {Year}");
Console.WriteLine($"حداکثر سرعت: {MaxSpeed} کیلومتر، وضعیت: {(_isRunning ? "روشن" : "خاموش")}");
}
}
// کلاس فرزند: خودروی مسابقهای
public class SportsCar : Vehicle
{
public bool TurboMode { get; private set; }
public int TurboBoost { get; private set; }
// سازنده که سازنده والد را فراخوانی میکند
public SportsCar(string brand, string model, int year, string engine, int maxSpeed, int turboBoost)
: base(brand, model, year, engine, maxSpeed)
{
TurboBoost = turboBoost;
TurboMode = false;
Console.WriteLine($"ماشین مسابقهای با قابلیت توربو {turboBoost} اسب بخار اضافه شد!");
}
// بازنویسی متد والد (Override)
public override void Start()
{
if (!_isRunning)
{
_isRunning = true;
Console.WriteLine($"🏎️ ماشین مسابقهای {Brand} {Model} با صدای خفن روشن شد!");
Console.WriteLine($"آماده برای سرعت تا {MaxSpeed} کیلومتر!");
}
}
// متد اختصاصی کلاس فرزند
public void ActivateTurbo()
{
if (_isRunning && !TurboMode)
{
TurboMode = true;
Console.WriteLine($"🚀 توربو فعال شد! قدرت اضافی: {TurboBoost} اسب بخار!");
Console.WriteLine($"حداکثر سرعت جدید: {MaxSpeed + 50} کیلومتر!");
}
else if (!_isRunning)
{
Console.WriteLine("ابتدا خودرو را روشن کنید!");
}
else
{
Console.WriteLine("توربو از قبل فعال است!");
}
}
public void DeactivateTurbo()
{
if (TurboMode)
{
TurboMode = false;
Console.WriteLine("توربو غیرفعال شد.");
}
}
}
// کلاس فرزند: کامیون
public class Truck : Vehicle
{
public int LoadCapacity { get; private set; }
public int CurrentLoad { get; private set; }
public Truck(string brand, string model, int year, string engine, int maxSpeed, int loadCapacity)
: base(brand, model, year, engine, maxSpeed)
{
LoadCapacity = loadCapacity;
CurrentLoad = 0;
Console.WriteLine($"کامیون با ظرفیت {loadCapacity} تن ساخته شد.");
}
public override void Start()
{
if (!_isRunning)
{
_isRunning = true;
Console.WriteLine($"🚛 کامیون {Brand} {Model} با موتور قدرتمند {_engine} روشن شد!");
Console.WriteLine($"بار فعلی: {CurrentLoad}/{LoadCapacity} تن");
}
}
public void LoadCargo(int weight)
{
if (CurrentLoad + weight <= LoadCapacity)
{
CurrentLoad += weight;
Console.WriteLine($"{weight} تن بار اضافه شد. بار کل: {CurrentLoad}/{LoadCapacity} تن");
}
else
{
Console.WriteLine($"ظرفیت کافی نیست! حداکثر {LoadCapacity - CurrentLoad} تن میتوانید اضافه کنید.");
}
}
public void UnloadCargo(int weight)
{
if (weight <= CurrentLoad)
{
CurrentLoad -= weight;
Console.WriteLine($"{weight} تن بار تخلیه شد. بار باقیمانده: {CurrentLoad} تن");
}
else
{
Console.WriteLine($"فقط {CurrentLoad} تن بار موجود است!");
}
}
}
class Program
{
static void Main()
{
Console.WriteLine("=== تست ماشین مسابقهای ===");
SportsCar ferrari = new SportsCar("فراری", "F8 Tributo", 2024, "V8 Twin-Turbo", 340, 200);
ferrari.DisplayBasicInfo();
ferrari.Start();
ferrari.ActivateTurbo();
ferrari.Stop();
Console.WriteLine("\n=== تست کامیون ===");
Truck truck = new Truck("ولوو", "FH16", 2023, "دیزل", 120, 25);
truck.DisplayBasicInfo();
truck.Start();
truck.LoadCargo(15);
truck.LoadCargo(12); // بیش از ظرفیت
truck.UnloadCargo(5);
truck.Stop();
Console.WriteLine("\n=== تست چندریختی ===");
Vehicle[] vehicles = { ferrari, truck };
foreach (Vehicle vehicle in vehicles)
{
Console.WriteLine($"\nشروع {vehicle.Brand} {vehicle.Model}:");
vehicle.Start(); // هر کدام متد خودشان را اجرا میکنند
}
Console.ReadKey();
}
}
🎭 چندریختی (Polymorphism)
چندریختی یعنی توانایی استفاده از یک رابط واحد برای انواع مختلف اشیاء. مثل اینکه همه حیوانات صدا میدهند، اما هر کدام صدای متفاوتی دارند.
using System;
using System.Collections.Generic;
// کلاس پایه انتزاعی
public abstract class Animal
{
public string Name { get; set; }
public int Age { get; set; }
public Animal(string name, int age)
{
Name = name;
Age = age;
}
// متد انتزاعی - باید در کلاسهای فرزند پیادهسازی شود
public abstract void MakeSound();
public abstract void Move();
// متد مجازی - میتواند بازنویسی شود
public virtual void Eat()
{
Console.WriteLine($"{Name} در حال خوردن است.");
}
// متد عمومی
public void Sleep()
{
Console.WriteLine($"{Name} در حال خوابیدن است. 😴");
}
}
public class Dog : Animal
{
public string Breed { get; set; }
public Dog(string name, int age, string breed) : base(name, age)
{
Breed = breed;
}
public override void MakeSound()
{
Console.WriteLine($"{Name} (سگ {Breed}) میگوید: واق واق! 🐕");
}
public override void Move()
{
Console.WriteLine($"{Name} در حال دویدن و بازی است!");
}
public override void Eat()
{
Console.WriteLine($"{Name} غذای سگ میخورد. 🦴");
}
// متد اختصاصی
public void Fetch()
{
Console.WriteLine($"{Name} توپ را میآورد!");
}
}
public class Cat : Animal
{
public bool IsIndoor { get; set; }
public Cat(string name, int age, bool isIndoor) : base(name, age)
{
IsIndoor = isIndoor;
}
public override void MakeSound()
{
Console.WriteLine($"{Name} (گربه {(IsIndoor ? "خانگی" : "ولگرد")}) میگوید: میو میو! 🐱");
}
public override void Move()
{
Console.WriteLine($"{Name} با ظرافت راه میرود.");
}
public override void Eat()
{
Console.WriteLine($"{Name} غذای گربه میخورد. 🐟");
}
public void Purr()
{
Console.WriteLine($"{Name} خرخر میکند! 😸");
}
}
public class Bird : Animal
{
public bool CanFly { get; set; }
public Bird(string name, int age, bool canFly) : base(name, age)
{
CanFly = canFly;
}
public override void MakeSound()
{
Console.WriteLine($"{Name} (پرنده) میگوید: جیک جیک! 🐦");
}
public override void Move()
{
if (CanFly)
Console.WriteLine($"{Name} در آسمان پرواز میکند! ✈️");
else
Console.WriteLine($"{Name} روی زمین راه میرود.");
}
public override void Eat()
{
Console.WriteLine($"{Name} دانه میخورد. 🌾");
}
}
class Program
{
static void Main()
{
// ایجاد لیستی از حیوانات مختلف
List animals = new List
{
new Dog("رکس", 3, "ژرمن شپرد"),
new Cat("مینو", 2, true),
new Bird("طوطی", 1, true),
new Dog("بادی", 5, "گلدن رتریور"),
new Cat("گربه سیاه", 4, false)
};
Console.WriteLine("=== نمایش چندریختی ===");
// استفاده از چندریختی - همه حیوانات با یک روش کنترل میشوند
foreach (Animal animal in animals)
{
Console.WriteLine($"\n--- {animal.Name} ({animal.Age} ساله) ---");
animal.MakeSound(); // هر حیوان صدای خودش را در میآورد
animal.Move(); // هر حیوان به شیوه خودش حرکت میکند
animal.Eat(); // هر حیوان غذای خودش را میخورد
animal.Sleep(); // همه یکسان میخوابند
}
Console.WriteLine("\n=== تست متدهای اختصاصی ===");
// دسترسی به متدهای اختصاصی با Type Casting
foreach (Animal animal in animals)
{
if (animal is Dog dog)
{
dog.Fetch();
}
else if (animal is Cat cat)
{
cat.Purr();
}
}
Console.WriteLine("\n=== شمارش انواع حیوانات ===");
CountAnimals(animals);
Console.ReadKey();
}
// متد برای شمارش انواع حیوانات
static void CountAnimals(List animals)
{
int dogCount = 0, catCount = 0, birdCount = 0;
foreach (Animal animal in animals)
{
switch (animal)
{
case Dog _:
dogCount++;
break;
case Cat _:
catCount++;
break;
case Bird _:
birdCount++;
break;
}
}
Console.WriteLine($"سگها: {dogCount}, گربهها: {catCount}, پرندگان: {birdCount}");
}
}
🚗 مثال اضافی: سیستم وسایل نقلیه
در این مثال، یک سیستم ساده برای وسایل نقلیه ایجاد میکنیم که شامل کلاس پایه Vehicle و کلاس فرزند SportsCar است.
// کلاس پایه وسیله نقلیه
public class Vehicle
{
private string _engine;
public string Brand { get; set; }
// ویژگی عمومی (Public Property)
public int Year { get; set; }
// سازنده
public Vehicle(string brand, int year, string engine)
{
Brand = brand;
Year = year;
_engine = engine;
}
// متد مجازی (Virtual Method)
public virtual void Start()
{
Console.WriteLine($"{Brand} با موتور {_engine} روشن شد!");
}
}
// کلاس فرزند (Derived Class)
public class SportsCar : Vehicle
{
public int TopSpeed { get; set; }
// سازنده که سازنده والد را فراخوانی میکند
public SportsCar(string brand, int year, string engine, int topSpeed)
: base(brand, year, engine)
{
TopSpeed = topSpeed;
}
// بازنویسی متد والد (Override)
public override void Start()
{
Console.WriteLine($"ماشین مسابقهای {Brand} با صدای خفن روشن شد! 🏎️");
}
// متد اختصاصی
public void Turbo()
{
Console.WriteLine($"توربو فعال! سرعت تا {TopSpeed} کیلومتر!");
}
}
class Program
{
static void Main()
{
SportsCar ferrari = new SportsCar("فراری", 2024, "V8", 350);
ferrari.Start();
ferrari.Turbo();
}
}
💪 تمرینهای عملی
حالا وقت تمرین است! این تمرینها به شما کمک میکنند مفاهیم OOP را عمیقتر درک کنید.
🎓 تمرین ۱: سیستم مدیریت کتابخانه
یک سیستم کتابخانه طراحی کنید که شامل موارد زیر باشد:
- کلاس پایه
LibraryItemبا ویژگیهای عنوان، شناسه، سال انتشار و وضعیت امانت - کلاس
Bookکه ازLibraryItemارثبری کند و نویسنده و تعداد صفحات داشته باشد - کلاس
Magazineکه ازLibraryItemارثبری کند و شماره مجله داشته باشد - متدهای امانت دادن و برگرداندن آیتمها
- متد جستجو بر اساس عنوان
جواب تمرین ۱: سیستم مدیریت کتابخانه
using System;
using System.Collections.Generic;
using System.Linq;
// کلاس پایه آیتم کتابخانه
public abstract class LibraryItem
{
protected string _id;
protected bool _isBorrowed;
public string Title { get; set; }
public string Id { get { return _id; } }
public int PublishYear { get; set; }
public bool IsBorrowed { get { return _isBorrowed; } }
public DateTime? BorrowDate { get; private set; }
public string BorrowerName { get; private set; }
public LibraryItem(string id, string title, int publishYear)
{
_id = id;
Title = title;
PublishYear = publishYear;
_isBorrowed = false;
}
// متد مجازی برای نمایش اطلاعات
public virtual void DisplayInfo()
{
Console.WriteLine($"شناسه: {_id}, عنوان: {Title}, سال انتشار: {PublishYear}");
Console.WriteLine($"وضعیت: {(_isBorrowed ? $"امانت داده شده به {BorrowerName}" : "موجود")}");
}
// متد امانت دادن
public virtual bool Borrow(string borrowerName)
{
if (!_isBorrowed)
{
_isBorrowed = true;
BorrowerName = borrowerName;
BorrowDate = DateTime.Now;
Console.WriteLine($"{Title} به {borrowerName} امانت داده شد.");
return true;
}
else
{
Console.WriteLine($"{Title} در حال حاضر امانت داده شده است.");
return false;
}
}
// متد برگرداندن
public virtual bool Return()
{
if (_isBorrowed)
{
Console.WriteLine($"{Title} از {BorrowerName} برگردانده شد.");
_isBorrowed = false;
BorrowerName = null;
BorrowDate = null;
return true;
}
else
{
Console.WriteLine($"{Title} امانت داده نشده است.");
return false;
}
}
// متد انتزاعی برای محاسبه جریمه
public abstract decimal CalculateFine();
}
// کلاس کتاب
public class Book : LibraryItem
{
public string Author { get; set; }
public int PageCount { get; set; }
public string Genre { get; set; }
public Book(string id, string title, int publishYear, string author, int pageCount, string genre)
: base(id, title, publishYear)
{
Author = author;
PageCount = pageCount;
Genre = genre;
}
public override void DisplayInfo()
{
Console.WriteLine($"📚 کتاب: {Title}");
Console.WriteLine($"نویسنده: {Author}, ژانر: {Genre}");
Console.WriteLine($"تعداد صفحات: {PageCount}, سال انتشار: {PublishYear}");
Console.WriteLine($"وضعیت: {(_isBorrowed ? $"امانت داده شده به {BorrowerName}" : "موجود")}");
}
public override decimal CalculateFine()
{
if (_isBorrowed && BorrowDate.HasValue)
{
int daysLate = (DateTime.Now - BorrowDate.Value).Days - 14; // مهلت ۱۴ روزه
return daysLate > 0 ? daysLate * 1000 : 0; // ۱۰۰۰ تومان در روز
}
return 0;
}
}
// کلاس مجله
public class Magazine : LibraryItem
{
public int IssueNumber { get; set; }
public string Publisher { get; set; }
public Magazine(string id, string title, int publishYear, int issueNumber, string publisher)
: base(id, title, publishYear)
{
IssueNumber = issueNumber;
Publisher = publisher;
}
public override void DisplayInfo()
{
Console.WriteLine($"📰 مجله: {Title}");
Console.WriteLine($"ناشر: {Publisher}, شماره: {IssueNumber}");
Console.WriteLine($"سال انتشار: {PublishYear}");
Console.WriteLine($"وضعیت: {(_isBorrowed ? $"امانت داده شده به {BorrowerName}" : "موجود")}");
}
public override decimal CalculateFine()
{
if (_isBorrowed && BorrowDate.HasValue)
{
int daysLate = (DateTime.Now - BorrowDate.Value).Days - 7; // مهلت ۷ روزه
return daysLate > 0 ? daysLate * 500 : 0; // ۵۰۰ تومان در روز
}
return 0;
}
}
// کلاس مدیریت کتابخانه
public class Library
{
private List _items;
public Library()
{
_items = new List();
}
public void AddItem(LibraryItem item)
{
_items.Add(item);
Console.WriteLine($"آیتم {item.Title} به کتابخانه اضافه شد.");
}
public LibraryItem SearchByTitle(string title)
{
return _items.FirstOrDefault(item =>
item.Title.Contains(title, StringComparison.OrdinalIgnoreCase));
}
public List SearchByAuthor(string author)
{
return _items.OfType()
.Where(book => book.Author.Contains(author, StringComparison.OrdinalIgnoreCase))
.Cast()
.ToList();
}
public void DisplayAllItems()
{
Console.WriteLine("\n=== فهرست کتابخانه ===");
foreach (var item in _items)
{
item.DisplayInfo();
Console.WriteLine("---");
}
}
public void DisplayBorrowedItems()
{
Console.WriteLine("\n=== آیتمهای امانت داده شده ===");
var borrowedItems = _items.Where(item => item.IsBorrowed);
foreach (var item in borrowedItems)
{
item.DisplayInfo();
Console.WriteLine($"جریمه: {item.CalculateFine():C}");
Console.WriteLine("---");
}
}
}
class Program
{
static void Main()
{
Library library = new Library();
// اضافه کردن آیتمها
library.AddItem(new Book("B001", "هری پاتر و سنگ جادو", 1997, "جی.کی. رولینگ", 320, "فانتزی"));
library.AddItem(new Book("B002", "شازده کوچولو", 1943, "آنتوان دو سنت اگزوپری", 120, "ادبیات"));
library.AddItem(new Magazine("M001", "مجله علم و فناوری", 2024, 150, "انتشارات علمی"));
library.AddItem(new Magazine("M002", "مجله کامپیوتر", 2024, 75, "انتشارات فناوری"));
// نمایش همه آیتمها
library.DisplayAllItems();
// تست امانت
var book1 = library.SearchByTitle("هری پاتر");
book1?.Borrow("احمد محمدی");
var magazine1 = library.SearchByTitle("علم و فناوری");
magazine1?.Borrow("فاطمه احمدی");
// نمایش آیتمهای امانت داده شده
library.DisplayBorrowedItems();
// برگرداندن
book1?.Return();
Console.ReadKey();
}
}
🏪 تمرین ۲: سیستم فروشگاه آنلاین
یک سیستم فروشگاه آنلاین طراحی کنید که شامل موارد زیر باشد:
- کلاس پایه
Productبا ویژگیهای نام، قیمت، موجودی و کد محصول - کلاسهای
Electronics،ClothingوBookکه ازProductارثبری کنند - کلاس
ShoppingCartبرای مدیریت سبد خرید - کلاس
Customerبرای مدیریت اطلاعات مشتری - محاسبه تخفیف بر اساس نوع محصول و مشتری
جواب تمرین ۲: سیستم فروشگاه آنلاین
using System;
using System.Collections.Generic;
using System.Linq;
// کلاس پایه محصول
public abstract class Product
{
protected string _productId;
protected decimal _price;
protected int _stock;
public string Name { get; set; }
public string ProductId { get { return _productId; } }
public decimal Price { get { return _price; } }
public int Stock { get { return _stock; } }
public string Description { get; set; }
public Product(string productId, string name, decimal price, int stock, string description)
{
_productId = productId;
Name = name;
_price = price;
_stock = stock;
Description = description;
}
// متد مجازی برای محاسبه تخفیف
public virtual decimal CalculateDiscount(int quantity)
{
return 0; // بدون تخفیف پیشفرض
}
// متد انتزاعی برای نمایش اطلاعات
public abstract void DisplayProductInfo();
// متد کاهش موجودی
public bool ReduceStock(int quantity)
{
if (_stock >= quantity)
{
_stock -= quantity;
return true;
}
return false;
}
// متد افزایش موجودی
public void AddStock(int quantity)
{
_stock += quantity;
}
}
// کلاس محصولات الکترونیکی
public class Electronics : Product
{
public string Brand { get; set; }
public int WarrantyMonths { get; set; }
public string Model { get; set; }
public Electronics(string productId, string name, decimal price, int stock, string description,
string brand, int warrantyMonths, string model)
: base(productId, name, price, stock, description)
{
Brand = brand;
WarrantyMonths = warrantyMonths;
Model = model;
}
public override decimal CalculateDiscount(int quantity)
{
// تخفیف ۵٪ برای خرید بیش از ۲ قطعه
if (quantity >= 2)
return 0.05m;
return 0;
}
public override void DisplayProductInfo()
{
Console.WriteLine($"📱 محصول الکترونیکی: {Name}");
Console.WriteLine($"برند: {Brand}, مدل: {Model}");
Console.WriteLine($"قیمت: {_price:C}, موجودی: {_stock}");
Console.WriteLine($"گارانتی: {WarrantyMonths} ماه");
Console.WriteLine($"توضیحات: {Description}");
}
}
// کلاس پوشاک
public class Clothing : Product
{
public string Size { get; set; }
public string Color { get; set; }
public string Material { get; set; }
public Clothing(string productId, string name, decimal price, int stock, string description,
string size, string color, string material)
: base(productId, name, price, stock, description)
{
Size = size;
Color = color;
Material = material;
}
public override decimal CalculateDiscount(int quantity)
{
// تخفیف ۱۰٪ برای خرید بیش از ۳ قطعه
if (quantity >= 3)
return 0.10m;
return 0;
}
public override void DisplayProductInfo()
{
Console.WriteLine($"👕 پوشاک: {Name}");
Console.WriteLine($"سایز: {Size}, رنگ: {Color}");
Console.WriteLine($"جنس: {Material}");
Console.WriteLine($"قیمت: {_price:C}, موجودی: {_stock}");
Console.WriteLine($"توضیحات: {Description}");
}
}
// کلاس کتاب
public class BookProduct : Product
{
public string Author { get; set; }
public string Publisher { get; set; }
public int Pages { get; set; }
public BookProduct(string productId, string name, decimal price, int stock, string description,
string author, string publisher, int pages)
: base(productId, name, price, stock, description)
{
Author = author;
Publisher = publisher;
Pages = pages;
}
public override decimal CalculateDiscount(int quantity)
{
// تخفیف ۱۵٪ برای خرید بیش از ۵ کتاب
if (quantity >= 5)
return 0.15m;
return 0;
}
public override void DisplayProductInfo()
{
Console.WriteLine($"📚 کتاب: {Name}");
Console.WriteLine($"نویسنده: {Author}");
Console.WriteLine($"ناشر: {Publisher}, صفحات: {Pages}");
Console.WriteLine($"قیمت: {_price:C}, موجودی: {_stock}");
Console.WriteLine($"توضیحات: {Description}");
}
}
// کلاس آیتم سبد خرید
public class CartItem
{
public Product Product { get; set; }
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
public decimal Discount { get; set; }
public decimal TotalPrice
{
get { return (UnitPrice * Quantity) * (1 - Discount); }
}
public CartItem(Product product, int quantity)
{
Product = product;
Quantity = quantity;
UnitPrice = product.Price;
Discount = product.CalculateDiscount(quantity);
}
}
// کلاس سبد خرید
public class ShoppingCart
{
private List _items;
public ShoppingCart()
{
_items = new List();
}
public bool AddItem(Product product, int quantity)
{
if (product.Stock >= quantity)
{
var existingItem = _items.FirstOrDefault(item => item.Product.ProductId == product.ProductId);
if (existingItem != null)
{
existingItem.Quantity += quantity;
existingItem.Discount = product.CalculateDiscount(existingItem.Quantity);
}
else
{
_items.Add(new CartItem(product, quantity));
}
Console.WriteLine($"{quantity} عدد {product.Name} به سبد خرید اضافه شد.");
return true;
}
else
{
Console.WriteLine($"موجودی کافی نیست! فقط {product.Stock} عدد موجود است.");
return false;
}
}
public void RemoveItem(string productId)
{
var item = _items.FirstOrDefault(i => i.Product.ProductId == productId);
if (item != null)
{
_items.Remove(item);
Console.WriteLine($"{item.Product.Name} از سبد خرید حذف شد.");
}
}
public decimal GetTotalAmount()
{
return _items.Sum(item => item.TotalPrice);
}
public void DisplayCart()
{
Console.WriteLine("\n=== سبد خرید ===");
if (_items.Count == 0)
{
Console.WriteLine("سبد خرید خالی است.");
return;
}
foreach (var item in _items)
{
Console.WriteLine($"{item.Product.Name} - تعداد: {item.Quantity}");
Console.WriteLine($"قیمت واحد: {item.UnitPrice:C}");
if (item.Discount > 0)
Console.WriteLine($"تخفیف: {item.Discount:P}");
Console.WriteLine($"قیمت کل: {item.TotalPrice:C}");
Console.WriteLine("---");
}
Console.WriteLine($"مجموع کل: {GetTotalAmount():C}");
}
public bool Checkout()
{
foreach (var item in _items)
{
if (!item.Product.ReduceStock(item.Quantity))
{
Console.WriteLine($"خطا: موجودی {item.Product.Name} کافی نیست.");
return false;
}
}
Console.WriteLine("خرید با موفقیت انجام شد!");
_items.Clear();
return true;
}
}
// کلاس مشتری
public class Customer
{
public string CustomerId { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public ShoppingCart Cart { get; private set; }
public bool IsPremium { get; set; }
public Customer(string customerId, string name, string email, string phone)
{
CustomerId = customerId;
Name = name;
Email = email;
Phone = phone;
Cart = new ShoppingCart();
IsPremium = false;
}
public void DisplayCustomerInfo()
{
Console.WriteLine($"\n=== اطلاعات مشتری ===");
Console.WriteLine($"نام: {Name}");
Console.WriteLine($"ایمیل: {Email}");
Console.WriteLine($"تلفن: {Phone}");
Console.WriteLine($"نوع عضویت: {(IsPremium ? "ویژه" : "عادی")}");
}
}
class Program
{
static void Main()
{
// ایجاد محصولات
var laptop = new Electronics("E001", "لپتاپ ایسوس", 25000000, 10, "لپتاپ گیمینگ", "ASUS", 24, "ROG Strix");
var shirt = new Clothing("C001", "پیراهن مردانه", 150000, 20, "پیراهن کتان", "L", "آبی", "کتان");
var book = new BookProduct("B001", "آموزش C#", 80000, 15, "کتاب جامع برنامهنویسی", "احمد محمدی", "انتشارات فناوری", 450);
// ایجاد مشتری
var customer = new Customer("CUST001", "علی احمدی", "ali@example.com", "09123456789");
customer.DisplayCustomerInfo();
// نمایش محصولات
Console.WriteLine("\n=== محصولات موجود ===");
laptop.DisplayProductInfo();
Console.WriteLine();
shirt.DisplayProductInfo();
Console.WriteLine();
book.DisplayProductInfo();
// اضافه کردن به سبد خرید
customer.Cart.AddItem(laptop, 1);
customer.Cart.AddItem(shirt, 3); // تخفیف ۱۰٪
customer.Cart.AddItem(book, 5); // تخفیف ۱۵٪
// نمایش سبد خرید
customer.Cart.DisplayCart();
// تسویه حساب
customer.Cart.Checkout();
Console.ReadKey();
}
}
💡 نکات مهم برای حل تمرینها:
- تجزیه مسئله: ابتدا مسئله را به بخشهای کوچکتر تقسیم کنید
- طراحی کلاسها: روابط بین کلاسها را مشخص کنید
- کپسولهسازی: از فیلدهای private و ویژگیهای public استفاده کنید
- وراثت: کدهای مشترک را در کلاس پایه قرار دهید
- چندریختی: از متدهای virtual و abstract استفاده کنید
- تست تدریجی: هر بخش را جداگانه تست کنید
- مستندسازی: کدهای خود را کامنتگذاری کنید