// نمایش
Console.WriteLine("All names: " + string.Join(", ", names)); // Ali, Reza, Sara, Ali
// حذف (اولین مورد)
names.Remove("Ali"); // حذف اولین "Ali"
Console.WriteLine("After remove: " + string.Join(", ", names)); // Reza, Sara, Ali
// حذف با ایندکس
names.RemoveAt(1); // حذف ایندکس 1 (Sara)
Console.WriteLine("After remove at 1: " + string.Join(", ", names)); // Reza, Ali
// بررسی وجود
bool hasReza = names.Contains("Reza");
Console.WriteLine($"Contains Reza? {hasReza}"); // True
// تعداد اعضا
Console.WriteLine($"Count: {names.Count}"); // 2
// پاک کردن همه
names.Clear();
Console.WriteLine($"After clear: {names.Count}"); // 0
حلقه زدن روی List:
csharp
List<int> scores = new List<int> { 18, 20, 15, 19, 17 };
// با foreach
foreach (int s in scores)
{
Console.WriteLine(s);
}
// با for
for (int i = 0; i < scores.Count; i++)
{
Console.WriteLine($"Index {i}: {scores[i]}");
}
---
⏱️ قسمت 8: آرایه دوبعدی (مقدماتی)
csharp
// آرایه 3x4 (3 سطر، 4 ستون)
int[,] matrix = new int[3, 4];
// مقداردهی
matrix[0, 0] = 1;
matrix[0, 1] = 2;
matrix[0, 2] = 3;
matrix[0, 3] = 4;
matrix[1, 0] = 5;
matrix[1, 1] = 6;
matrix[1, 2] = 7;
matrix[1, 3] = 8;
// مقداردهی مستقیم
int[,] numbers = {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 }
};
// حلقه زدن روی آرایه دوبعدی
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
Console.Write(numbers[i, j] + " ");
}
Console.WriteLine();
}
---
✅ تمرین نهایی درس ششم
برنامهای بنویسید که:
1. یک آرایه از 5 نمره دانشجو بسازد
2. با حلقه، مجموع و میانگین را محاسبه کند
3. یک List از نام دانشجوها بسازد
4. از کاربر نام بگیرد و به لیست اضافه کند
5. امکان جستجو در لیست را با Contains بدهد
6. بالاترین نمره را از آرایه پیدا کند
csharp
using System;
using System.Collections.Generic;
// قسمت 1: آرایه نمرات
int[] scores = { 18, 20, 15, 19, 17 };
// محاسبه مجموع و میانگین
int sum = 0;
foreach (int score in scores)
{
sum += score;
}
double average = (double)sum / scores.Length;
Console.WriteLine($"Sum: {sum}, Average: {average:F2}");
// پیدا کردن بالاترین نمره
int max = scores[0];
foreach (int score in scores)
{
if (score > max)
max = score;
}
Console.WriteLine($"Highest score: {max}");
// قسمت 2: لیست نام دانشجوها
List<string> students = new List<string> { "Ali", "Reza", "Sara" };
Console.WriteLine("\nCurrent students: " + string.Join(", ", students));
// افزودن دانشجو جدید
Console.Write("Enter new student name: ");
string newStudent = Console.ReadLine();
students.Add(newStudent);
Console.WriteLine("After adding: " + string.Join(", ", students));
// جستجو در لیست
Console.Write("\nSearch for a name: ");
string search = Console.ReadLine();
if (students.Contains(search))
{
Console.WriteLine($"Yes, {search} is in the list!");
}
else
{
Console.WriteLine($"No, {search} is not in the list.");
}
Console.WriteLine("\nPress Enter to exit...");
Console.ReadLine();
`--- 📌 جمعبندی درس ششم مفهوم آرایه (Array) لیست (List) تعریف int[] arr = new int[5]; List<int> list = new List<int>(); اندازه arr.Length list.Count افزودن ❌ list.Add(item) حذف ❌ list.Remove(item) دسترسی arr[index] list[index] نکات کلیدی: · ایندکس همیشه از 0 شروع میشود · آرایه اندازه ثابت دارد · لیست اندازه متغیر دارد · برای استفاده از List نیاز به using System.Collections.Generic; --- 🧪 تمرین برای شما 1. آرایهای از 7 عدد بسازید و بگویید چند عدد زوج وجود دارد 2. List ای از 5 اسم بسازید و اسمی که کاربر میگوید را حذف کنید 3. برنامهای بنویسید که 5 عدد از کاربر بگیرد، در لیست ذخیره کند و بعد میانگین را چاپ کند --- اگر این درس را کامل فهمیدید، بگویید تا درس هفتم (متدها و توابع) را شروع کنیم. سوالی بود بپرسید.
خیلی خوب، رسیدیم به درس هفتم: متدها (Method) یا توابع در سیشارپ.
این یکی از مهمترین درسهای برنامهنویسی است. متدها به شما اجازه میدهند کدتان را مرتب، قابل استفاده مجدد و خواناتر کنید.
یک پروژه جدید بسازید (dotnet new console) و کدها را همراه من بنویسید و اجرا کنید.
---
📘 درس هفتم – متدها (Methods)
🎯 سرفصلها:
1. متد چیست و چرا نیاز داریم؟
2. ساختار یک متد
3. متد بدون پارامتر و بدون خروجی
4. متد با پارامتر
5. متد با خروجی (return)
6. متد با چند پارامتر
7. متد با پارامتر پیشفرض
8. فراخوانی متد در متد دیگر
9. تمرین جامع
---
⏱️ قسمت 1: متد چیست؟
متد = یک تکه کد که نام دارد و میتوانیم چند بار صدا بزنیم.
بدون متد (کد بد - تکرار):
csharp
Console.WriteLine("Welcome to our program!");
Console.WriteLine("Please enter your name...");
// همین پیام را 10 بار دیگر باید بنویسیم!
با متد (کد خوب):
csharp
ShowWelcomeMessage();
ShowWelcomeMessage();
ShowWelcomeMessage(); // هر چند بار که بخواهیم
void ShowWelcomeMessage()
{
Console.WriteLine("Welcome to our program!");
Console.WriteLine("Please enter your name...");
}
---
⏱️ قسمت 2: ساختار یک متد
csharp
[نوع_خروجی] [نام_متد]([پارامترها])
{
// بدنه متد
return مقدار; // اگر نوع خروجی void نباشد
}
سادهترین متد (بدون ورودی و بدون خروجی):
csharp
void SayHello()
{
Console.WriteLine("Hello World!");
}
// فراخوانی:
SayHello();
---
⏱️ قسمت 3: متد بدون پارامتر و بدون خروجی (void)
csharp
void ShowMenu()
{
Console.WriteLine("=== Main Menu ===");
Console.WriteLine("1. Add");
Console.WriteLine("2. Subtract");
Console.WriteLine("3. Multiply");
Console.WriteLine("4. Divide");
Console.WriteLine("=================");
}
// استفاده
ShowMenu();
ShowMenu(); // میتوانیم چند بار صدا بزنیم
---
⏱️ قسمت 4: متد با پارامتر (ورودی)
پارامترها را داخل () مینویسیم.
csharp
void Greet(string name)
{
Console.WriteLine($"Hello {name}! Welcome!");
}
// فراخوانی
Greet("Ali");
Greet("Sara");
Greet("Reza");
متد با چند پارامتر:
csharp
void PrintFullName(string firstName, string lastName)
{
Console.WriteLine($"Full name: {firstName} {lastName}");
}
// فراخوانی
PrintFullName("Mohammad", "Rezaei");
PrintFullName("Sara", "Ahmadi");
---
⏱️ قسمت 5: متد با خروجی (return)
اگر متد یک نتیجه برمیگرداند، نوع خروجی را مشخص میکنیم.
csharp
int Add(int a, int b)
{
int result = a + b;
return result; // برگرداندن نتیجه
}
// استفاده
int sum = Add(5, 3);
Console.WriteLine(sum); // 8
// یا مستقیم چاپ کنیم
Console.WriteLine(Add(10, 20)); // 30
مثالهای بیشتر:
csharp
// جمع دو عدد اعشاری
double Multiply(double x, double y)
{
return x * y;
}
// بررسی زوج بودن
bool IsEven(int number)
{
return number % 2 == 0;
}
// استفاده
double product = Multiply(3.5, 2);
Console.WriteLine(product); // 7
if (IsEven(7))
{
Console.WriteLine("Even");
}
else
{
Console.WriteLine("Odd");
}
---
⏱️ قسمت 6: انواع خروجی در متدها
نوع خروجی معنی مثال return
void هیچ چیزی برنمیگرداند return; (اختیاری)
int عدد صحیح return 5;
double عدد اعشاری return 3.14;
string متن return "hi";
bool true/false return true;
int[] آرایه return new int[]{1,2,3};
csharp
string GetGreeting(string name)
{
return $"Good morning, {name}!";
}
int[] GetNumbers()
{
return new int[] { 10, 20, 30 };
}
// استفاده
string msg = GetGreeting("Ali");
Console.WriteLine(msg);
int[] arr = GetNumbers();
foreach (int n in arr)
{
Console.WriteLine(n);
}
---
⏱️ قسمت 7: متد با پارامتر پیشفرض (Default Parameter)
میتوانیم برای پارامترها مقدار پیشفرض تعیین کنیم.
csharp
void Greet(string name, string title = "Dear")
{
Console.WriteLine($"Hello {title} {name}");
}
// دو روش فراخوانی
Greet("Ali", "Mr."); // Hello Mr. Ali
Greet("Sara"); // Hello Dear Sara (از پیشفرض استفاده میکند)
مثال دیگر:
csharp
double CalculatePrice(double basePrice, double tax = 0.09)
{
return basePrice + (basePrice * tax);
}
Console.WriteLine(CalculatePrice(100)); // 109 (مالیات 9%)
Console.WriteLine(CalculatePrice(100, 0.15)); // 115 (مالیات 15%)
---
⏱️ قسمت 8: فراخوانی متد در متد دیگر
csharp
int Add(int a, int b)
{
return a + b;
}
int Multiply(int a, int b)
{
return a * b;
}
int Calculate(int x, int y)
{
int sum = Add(x, y);
int product = Multiply(x, y);
return sum + product;
}
// استفاده
int result = Calculate(3, 4); // Add(3,4)=7, Multiply(3,4)=12 → 7+12=19
Console.WriteLine(result); // 19
---
⏱️ قسمت 9: متدهای محاسباتی کامل
csharp
// محاسبه توان
int Power(int baseNumber, int exponent)
{
int result = 1;
for (int i = 0; i < exponent; i++)
{
result *= baseNumber;
}
return result;
}
// فاکتوریل
int Factorial(int n)
{
int result = 1;
for (int i = 1; i <= n; i++)
{
result *= i;
}
return result;
}
// استفاده
Console.WriteLine(Power(2, 5)); // 32
Console.WriteLine(Factorial(5)); // 120
---
⏱️ قسمت 10: متد برای کار با آرایه
csharp
// پیدا کردن بزرگترین عدد در آرایه
int FindMax(int[] numbers)
{
int max = numbers[0];
foreach (int num in numbers)
{
if (num > max)
max = num;
}
return max;
}
// محاسبه میانگین
double CalculateAverage(int[] numbers)
{
int sum = 0;
foreach (int num in numbers)
{
sum += num;
}
return (double)sum / numbers.Length;
}
// استفاده
int[] scores = { 18, 20, 15, 19, 17 };
Console.WriteLine($"Max: {FindMax(scores)}");
Console.WriteLine($"Average: {CalculateAverage(scores):F2}");
---
✅ تمرین نهایی درس هفتم
برنامهای بنویسید که متدهای زیر را داشته باشد:
1. ShowMenu() – نمایش منوی اصلی
2. Add(a, b) – جمع دو عدد
3. Subtract(a, b) – تفریق دو عدد
4. Multiply(a, b) – ضرب دو عدد
5. Divide(a, b) – تقسیم دو عدد (با مدیریت تقسیم بر صفر)
6. IsValidNumber(input) – بررسی اینکه کاربر عدد وارد کرده باشد
csharp
using System;
void ShowMenu()
{
Console.Clear();
Console.WriteLine("=== Calculator ===");
Console.WriteLine("1. Add");
Console.WriteLine("2. Subtract");
Console.WriteLine("3. Multiply");
Console.WriteLine("4. Divide");
Console.WriteLine("5. Exit");
Console.WriteLine("=================");
}
int Add(int a, int b)
{
return a + b;
}
int Subtract(int a, int b)
{
return a - b;
}
int Multiply(int a, int b)
{
return a * b;
}
double Divide(int a, int b)
{
if (b == 0)
{
Console.WriteLine("Error: Cannot divide by zero!");
return 0;
}
return (double)a / b;
}
int GetNumber(string prompt)
{
int number;
while (true)
{
Console.Write(prompt);
string input = Console.ReadLine();
if (int.TryParse(input, out number))
{
return number;
}
Console.WriteLine("Invalid input! Please enter a number.");
}
}
// برنامه اصلی
int choice;
do
{
ShowMenu();
Console.Write("Choose an option: ");
string input = Console.ReadLine();
if (!int.TryParse(input, out choice))
{
Console.WriteLine("Invalid choice! Press Enter to continue...");
Console.ReadLine();
continue;
}
if (choice >= 1 && choice <= 4)
{
int num1 = GetNumber("Enter first number: ");
int num2 = GetNumber("Enter second number: ");
switch (choice)
{
case 1:
Console.WriteLine($"Result: {Add(num1, num2)}");
break;
case 2:
Console.WriteLine($"Result: {Subtract(num1, num2)}");
break;
case 3:
Console.WriteLine($"Result: {Multiply(num1, num2)}");
break;
case 4:
Console.WriteLine($"Result: {Divide(num1, num2):F2}");
break;
}
Console.WriteLine("Press Enter to continue...");
Console.ReadLine();
}
else if (choice != 5)
{
Console.WriteLine("Invalid option! Press Enter to continue...");
Console.ReadLine();
}
}
while (choice != 5);
Console.WriteLine("Goodbye!");
Console.ReadLine();
---
📌 جمعبندی درس هفتم
بخش مثال
تعریف متد void SayHello() { ... }
فراخوانی متد SayHello();
پارامتر void Greet(string name) { ... }
خروجی (return) int Add(int a, int b) { return a + b; }
پارامتر پیشفرض void Log(string msg, int level = 1) { ... }
قوانین مهم:
· نام متد باید معنیدار باشد (Verb یا فعل)
· هر متد یک کار مشخص انجام دهد
· از تکرار کد با متد جلوگیری کنید
· متدها را قبل از استفاده تعریف کنید (یا بعد از Main)
---
🧪 تمرین برای شما
1. متدی بنویسید که یک آرایه بگیرد و مجموع آن را برگرداند
2. متدی بنویسید که یک string بگیرد و تعداد حروف بزرگ آن را برگرداند
3. متدی بنویسید که دو عدد بگیرد و هر سه عمل جمع، تفریق و ضرب را در یک متد برگرداند (با چند خروجی) – راهنمایی: میتوانید از out parameter استفاده کنید
---
اگر این درس را کامل فهمیدید، بگویید تا درس هشتم (کلاسها و شیءگرایی) را شروع کنیم. سوالی بود بپرسید.
خیلی خوب، رسیدیم به درس هشتم: کلاسها (Class) و شیءگرایی (Object-Oriented Programming).
این درس یکی از مهمترین مباحث سیشارپ است. کلاسها به شما اجازه میدهند داده و رفتار را در یک واحد سازماندهی کنید.
---
📘 درس هشتم – کلاسها و شیءگرایی
🎯 سرفصلها:
1. شیءگرایی چیست؟
2. کلاس و شیء (Class و Object)
3. فیلدها (متغیرهای کلاس)
4. متدهای کلاس
5. سازنده (Constructor)
6. ویژگیها (Property) – get و set
7. سطح دسترسی (public, private)
8. تمرین جامع
---
⏱️ قسمت 1: شیءگرایی چیست؟
شیءگرایی = مدلسازی اشیای دنیای واقعی در برنامه
مثال: یک ماشین را در نظر بگیرید:
· ویژگیها (فیلدها): رنگ، مدل، سرعت
· کارها (متدها): استارت زدن، ترمز کردن، گاز دادن
---
⏱️ قسمت 2: کلاس و شیء
کلاس = نقشه یا قالبی برای ساختن اشیاء
شیء = نمونهای از آن کلاس (ساخته شده از روی نقشه)
csharp
// تعریف کلاس (نقشه)
class Car
{
public string color;
public string model;
public void Start()
{
Console.WriteLine("Car is starting...");
}
}
// استفاده در Main
class Program
{
static void Main()
{
// ساختن شیء (نمونه) از کلاس Car
Car myCar = new Car();
myCar.color = "Red";
myCar.model = "BMW";
myCar.Start();
Console.WriteLine($"My car is {myCar.color} {myCar.model}");
}
}
---
⏱️ قسمت 3: فیلدها (متغیرهای کلاس)
فیلدها همان متغیرهایی هستند که به کلاس تعلق دارند.
csharp
class Student
{
// فیلدها
public string name;
public int age;
public double score;
}
// استفاده
Student s1 = new Student();
s1.name = "Ali";
s1.age = 20;
s1.score = 18.5;
Student s2 = new Student();
s2.name = "Sara";
s2.age = 19;
s2.score = 19.5;
Console.WriteLine($"{s1.name}: {s1.score}");
Console.WriteLine($"{s2.name}: {s2.score}");
---
⏱️ قسمت 4: متدهای کلاس
متدها کارهایی هستند که شیء میتواند انجام دهد.
csharp
class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
public int Subtract(int a, int b)
{
return a - b;
}
public void ShowInfo()
{
Console.WriteLine("This is a calculator class");
}
}
// استفاده
Calculator calc = new Calculator();
int result = calc.Add(10, 5);
Console.WriteLine(result); // 15
calc.ShowInfo();
---
⏱️ قسمت 5: سازنده (Constructor)
سازنده = متدی که هنگام ساخته شدن شیء اجرا میشود
نام سازنده دقیقاً مثل نام کلاس است و void ندارد.
csharp
class Person
{
public string name;
public int age;
// سازنده (بدون پارامتر)
public Person()
{
Console.WriteLine("A person object is created!");
name = "Unknown";
age = 0;
}
// سازنده با پارامتر (Overloading)
public Person(string personName, int personAge)
{
Console.WriteLine($"Creating person: {personName}");
name = personName;
age = personAge;
}
public void Introduce()
{
Console.WriteLine($"Hi, I'm {name} and I'm {age} years old");
}
}
// استفاده
Person p1 = new Person(); // سازنده اول
Person p2 = new Person("Ali", 25); // سازنده دوم
p1.Introduce(); // Hi, I'm Unknown and I'm 0 years old
p2.Introduce(); // Hi, I'm Ali and I'm 25 years old
---
⏱️ قسمت 6: ویژگیها (Property) – get و set
Property راهی برای کنترل دسترسی به فیلدها است.
بدون Property (فیلد عمومی - خطرناک):
csharp
class BankAccount
{
public double balance; // هر کسی میتواند مستقیم تغییر دهد!
}
// مشکل: کسی میتواند موجودی را منفی کند
BankAccount acc = new BankAccount();
acc.balance = -1000; // خطای منطقی!
با Property (کنترل شده):
`csharp class BankAccount { private double balance; // فیلد خصوصی (دسترسی مستقیم نداریم) // Property public double Balance { get { return balance; } // خواندن مقدار set { if (value >= 0) // value = مقداری که کاربر میدهد balance = value; else Console.WriteLine("Balance cannot be negative!"); } } }
// استفاده
BankAccount acc = new BankAccount();
acc.Balance = 1000; // set اجرا میشود
Console.WriteLine(acc.Balance); // get اجرا میشود (1000)
acc.Balance = -500; // خطا میدهد و مقدار قبلی باقی میماند
Property ساده (Auto-Implemented Property):
csharp
class Product
{
public string Name { get; set; } // خودکار
public double Price { get; set; } // خودکار
public int Stock { get; set; }
}
// استفاده
Product p = new Product();
p.Name = "Laptop";
p.Price = 15000000;
p.Stock = 10;
---
⏱️ قسمت 7: سطح دسترسی (Access Modifiers)
سطح دسترسی معنی
public همه جا قابل دسترس است
private فقط داخل همان کلاس قابل دسترس است
protected داخل کلاس و کلاسهای فرزند
internal داخل همان پروژه
csharp
class Example
{
public int publicField = 1; // همه میبینند
private int privateField = 2; // فقط داخل Example
protected int protectedField = 3; // Example و کلاسهای ارثبر
internal int internalField = 4; // داخل همین پروژه
public void ShowPrivate()
{
Console.WriteLine(privateField); // ✅ داخل کلاس میشود
}
}
// در Main:
Example ex = new Example();
ex.publicField = 10; // ✅
// ex.privateField = 20; // ❌ خطا
ex.ShowPrivate(); // ✅ از طریق متد عمومی
---
⏱️ قسمت 8: مثال کامل – کلاس Student
csharp
class Student
{
// فیلدهای خصوصی
private string name;
private int age;
private double[] scores;
// سازنده
public Student(string studentName, int studentAge)
{
name = studentName;
age = studentAge;
scores = new double[0];
Console.WriteLine($"Student {name} created");
}
// Property
public string Name
{
get { return name; }
set { name = value; }
}
public int Age
{
get { return age; }
set
{
if (value >= 0 && value <= 120)
age = value;
else
Console.WriteLine("Invalid age!");
}
}
// متدها
public void AddScore(double score)
{
double[] newScores = new double[scores.Length + 1];
for (int i = 0; i < scores.Length; i++)
{
newScores[i] = scores[i];
}
newScores[scores.Length] = score;
scores = newScores;
}
public double GetAverage()
{
if (scores.Length == 0)
return 0;
double sum = 0;
foreach (double s in scores)
{
sum += s;
}
return sum / scores.Length;
}
public void ShowInfo()
{
Console.WriteLine($"Student: {name}, Age: {age}");
Console.WriteLine($"Average score: {GetAverage():F2}");
}
}
// استفاده در Main
Student s = new Student("Mohammad", 20);
s.AddScore(18);
s.AddScore(19);
s.AddScore(17.5);
s.ShowInfo();
---
✅ تمرین نهایی درس هشتم
برنامهای بنویسید که یک کلاس BankAccount بسازد با مشخصات زیر:
· فیلدهای خصوصی: accountNumber، balance، ownerName
· سازنده برای مقداردهی اولیه
· Property برای خواندن شماره حساب و موجودی (بدون set)
· Property برای نام صاحب حساب (get و set)
· متد Deposit(double amount) – افزایش موجودی
· متد Withdraw(double amount) – کاهش موجودی (اگر موجودی کافی نباشد خطا بدهد)
· متد ShowInfo() – نمایش اطلاعات
csharp
class BankAccount
{
private string accountNumber;
private double balance;
private string ownerName;
public BankAccount(string number, string owner, double initialBalance)
{
accountNumber = number;
ownerName = owner;
balance = (initialBalance >= 0) ? initialBalance : 0;
}
public string AccountNumber
{
get { return accountNumber; }
}
public double Balance
{
get { return balance; }
}
public string OwnerName
{
get { return ownerName; }
set { ownerName = value; }
}
public void Deposit(double amount)
{
if (amount > 0)
{
balance += amount;
Console.WriteLine($"Deposited: {amount:C}");
}
else
{
Console.WriteLine("Invalid deposit amount!");
}
}
public void Withdraw(double amount)
{
if (amount > 0 && amount <= balance)
{
balance -= amount;
Console.WriteLine($"Withdrawn: {amount:C}");
}
else if (amount > balance)
{
Console.WriteLine("Insufficient balance!");
}
else
{
Console.WriteLine("Invalid withdraw amount!");
}
}
public void ShowInfo()
{
Console.WriteLine($"Account: {accountNumber}");
Console.WriteLine($"Owner: {ownerName}");
Console.WriteLine($"Balance: {balance:C}");
}
}
// برنامه اصلی
class Program
{
static void Main()
{
BankAccount myAccount = new BankAccount("IR123456789", "Ali Rezaei", 1000000);
myAccount.ShowInfo();
Console.WriteLine();
myAccount.Deposit(500000);
myAccount.Withdraw(300000);
myAccount.Withdraw(2000000); // موجودی کافی نیست
Console.WriteLine();
myAccount.ShowInfo();
Console.WriteLine("\nPress Enter to exit...");
Console.ReadLine();
}
}
`--- 📌 جمعبندی درس هشتم مفهوم مثال تعریف کلاس class Car { ... } ساختن شیء Car myCar = new Car(); فیلد public string color; متد public void Start() { ... } سازنده public Car() { ... } Property public string Color { get; set; } public همه جا قابل دسترس private فقط داخل همان کلاس --- 🧪 تمرین برای شما 1. یک کلاس Book بسازید با: عنوان، نویسنده، قیمت، تعداد صفحات 2. یک کلاس Rectangle بسازید با: طول، عرض، و متدهای مساحت و محیط 3. یک کلاس Clock بسازید که زمان را نگه دارد و متد Tick() هر بار یک ثانیه اضافه کند --- اگر این درس را کامل فهمیدید، بگویید تا درس نهم (ارثبری و polymorphism) را شروع کنیم. سوالی بود بپرسید.
خیلی خوب، رسیدیم به درس نهم: ارثبری (Inheritance) و چندریختی (Polymorphism).
این درس شما را وارد دنیای حرفهای شیءگرایی میکند.
یک پروژه جدید بسازید (dotnet new console) و کدها را همراه من بنویسید و اجرا کنید.
---
📘 درس نهم – ارثبری و چندریختی
🎯 سرفصلها:
1. ارثبری چیست؟ (پدر و فرزند)
2. کلمه کلیدی : و base
3. بازنویسی متدها با virtual و override
4. کلاسهای مشتق شده (Derived Classes)
5. چندریختی (Polymorphism)
6. کلاس abstract (چکیده)
7. کلمه کلیدی sealed
8. تمرین جامع
---
⏱️ قسمت 1: ارثبری چیست؟
ارثبری = یک کلاس میتواند ویژگیها و رفتارهای کلاس دیگر را به ارث ببرد.
کلاس پدر (Base Class) → کلاس فرزند (Derived Class)
مثال ساده:
csharp
// کلاس پدر (Base Class)
class Animal
{
public string Name { get; set; }
public void Eat()
{
Console.WriteLine($"{Name} is eating...");
}
}
// کلاس فرزند (Derived Class) - از Animal ارث میبرد
class Dog : Animal
{
public void Bark()
{
Console.WriteLine($"{Name} is barking: Woof! Woof!");
}
}
// استفاده
Dog myDog = new Dog();
myDog.Name = "Rex"; // از کلاس Animal
myDog.Eat(); // از کلاس Animal
myDog.Bark(); // از خودش
📌 نکته: فرزند همه چیز پدر را دارد (به جز سازندههای خصوصی).
---
⏱️ قسمت 2: کلمه کلیدی base
از base برای دسترسی به اعضای کلاس پدر استفاده میشود.
csharp
class Vehicle
{
public string Brand { get; set; }
public Vehicle(string brand)
{
Brand = brand;
Console.WriteLine("Vehicle constructor called");
}
public void Start()
{
Console.WriteLine("Vehicle is starting...");
}
}
class Car : Vehicle
{
public string Model { get; set; }
// فراخوانی سازنده پدر با base
public Car(string brand, string model) : base(brand)
{
Model = model;
Console.WriteLine("Car constructor called");
}
public void ShowInfo()
{
base.Start(); // فراخوانی متد پدر
Console.WriteLine($"Brand: {Brand}, Model: {Model}");
}
}
// استفاده
Car myCar = new Car("BMW", "X5");
myCar.ShowInfo();
خروجی:
Vehicle constructor called
Car constructor called
Vehicle is starting...
Brand: BMW, Model: X5
---
⏱️ قسمت 3: بازنویسی متدها (virtual و override)
گاهی فرزند میخواهد رفتار پدر را تغییر دهد.
کلیدواژه کاربرد
virtual متدی که میتوان در فرزند بازنویسی شود
override بازنویسی متد مجازی در فرزند
csharp
class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("Animal makes a sound");
}
}
class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("Dog barks: Woof! Woof!");
}
}
class Cat : Animal
{
public override void MakeSound()
{
Console.WriteLine("Cat meows: Meow! Meow!");
}
}
// استفاده
Animal a1 = new Animal();
Animal a2 = new Dog();
Animal a3 = new Cat();
a1.MakeSound(); // Animal makes a sound
a2.MakeSound(); // Dog barks: Woof! Woof!
a3.MakeSound(); // Cat meows: Meow! Meow!
---
⏱️ قسمت 4: چندریختی (Polymorphism)
چندریختی = یک اسم (نوع پدر)، چند شکل (رفتار فرزند)
`csharp class Shape { public virtual double GetArea() { return 0; } public virtual void Draw() { Console.WriteLine("Drawing a shape"); } } class Circle : Shape { public double Radius { get; set; } public Circle(double radius) { Radius = radius; } public override double GetArea() { return Math.PI * Radius * Radius; } public override void Draw() { Console.WriteLine($"Drawing a circle with radius {Radius}"); } } class Rectangle : Shape { public double Width { get; set; } public double Height { get; set; } public Rectangle(double width, double height) { Width = width; Height = height; } public override double GetArea() { return Width * Height; } public override void Draw() { Console.WriteLine($"Drawing a rectangle {Width}x{Height}"); } }
// چندریختی در عمل
Shape[] shapes = new Shape[3];
shapes[0] = new Circle(5);
shapes[1] = new Rectangle(4, 6);
shapes[2] = new Circle(3);
foreach (Shape shape in shapes)
{
shape.Draw();
Console.WriteLine($"Area: {shape.GetArea():F2}");
Console.WriteLine();
}
---
⏱️ قسمت 5: کلاس abstract (چکیده)
کلاس abstract = کلاسی که نمیتوان از آن شیء ساخت، فقط برای ارثبری است.
csharp
// کلاس abstract
abstract class Employee
{
public string Name { get; set; }
public int Id { get; set; }
public Employee(string name, int id)
{
Name = name;
Id = id;
}
// متد abstract - بدون بدنه، فرزند حتماً باید پیادهسازی کند
public abstract double CalculateSalary();
// متد معمولی
public void ShowInfo()
{
Console.WriteLine($"Employee: {Name} (ID: {Id})");
}
}
class FullTimeEmployee : Employee
{
public double MonthlySalary { get; set; }
public FullTimeEmployee(string name, int id, double salary) : base(name, id)
{
MonthlySalary = salary;
}
public override double CalculateSalary()
{
return MonthlySalary;
}
}
class PartTimeEmployee : Employee
{
public double HourlyRate { get; set; }
public int HoursWorked { get; set; }
public PartTimeEmployee(string name, int id, double rate, int hours) : base(name, id)
{
HourlyRate = rate;
HoursWorked = hours;
}
public override double CalculateSalary()
{
return HourlyRate * HoursWorked;
}
}
// استفاده
// Employee e = new Employee(); // ❌ خطا - نمیتوان از کلاس abstract شیء ساخت
FullTimeEmployee fte = new FullTimeEmployee("Ali", 101, 5000000);
PartTimeEmployee pte = new PartTimeEmployee("Sara", 102, 50000, 80);
fte.ShowInfo();
Console.WriteLine($"Salary: {fte.CalculateSalary()}");
pte.ShowInfo();
Console.WriteLine($"Salary: {pte.CalculateSalary()}");
---
⏱️ قسمت 6: کلاس sealed (مهر و موم شده)
کلاس sealed = کلاسی که نمیتوان از آن ارثبری کرد.
csharp
sealed class FinalClass
{
public void DoSomething()
{
Console.WriteLine("This class cannot be inherited");
}
}
// class Child : FinalClass { } // ❌ خطا - نمیتوان از sealed ارث برد
متد sealed: در کلاس فرزند، نمیتوان بیشتر از این بازنویسی کرد.
csharp
class Parent
{
public virtual void MyMethod()
{
Console.WriteLine("Parent");
}
}
class Child : Parent
{
public sealed override void MyMethod() // sealed در این سطح
{
Console.WriteLine("Child");
}
}
// class GrandChild : Child
// {
// public override void MyMethod() { } // ❌ خطا - متد sealed است
// }
---
⏱️ قسمت 7: مثال کامل – سیستم حیوانات
csharp
using System;
// کلاس abstract
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 virtual void Move()
{
Console.WriteLine($"{Name} is moving");
}
public void ShowInfo()
{
Console.WriteLine($"Name: {Name}, Age: {Age}");
MakeSound();
Move();
}
}
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} barks: Woof! Woof!");
}
public override void Move()
{
Console.WriteLine($"{Name} runs happily");
}
}
class Bird : Animal
{
public double WingSpan { get; set; }
public Bird(string name, int age, double wingSpan) : base(name, age)
{
WingSpan = wingSpan;
}
public override void MakeSound()
{
Console.WriteLine($"{Name} chirps: Tweet! Tweet!");
}
public override void Move()
{
Console.WriteLine($"{Name} flies with {WingSpan}m wingspan");
}
}
class Fish : Animal
{
public string WaterType { get; set; } // Fresh or Salt
public Fish(string name, int age, string waterType) : base(name, age)
{
WaterType = waterType;
}
public override void MakeSound()
{
Console.WriteLine($"{Name} makes bubble sounds...");
}
public override void Move()
{
Console.WriteLine($"{Name} swims in {WaterType} water");
}
}
// برنامه اصلی
class Program
{
static void Main()
{
Animal[] animals = new Animal[3];
animals[0] = new Dog("Rex", 3, "German Shepherd");
animals[1] = new Bird("Tweety", 1, 0.25);
animals[2] = new Fish("Nemo", 2, "Salt");
foreach (Animal animal in animals)
{
animal.ShowInfo();
Console.WriteLine();
}
Console.WriteLine("Press Enter to exit...");
Console.ReadLine();
}
}
---
✅ تمرین نهایی درس نهم
سیستمی برای محاسبه حقوق کارمندان طراحی کنید:
1. کلاس abstract Employee با:
· فیلدهای: Name, ID, BaseSalary
· متد abstract CalculateSalary()
2. کلاس Manager : Employee
· Bonus اضافی
· حقوق = BaseSalary + Bonus
3. کلاس SalesPerson : Employee
· Commission (درصد فروش)
· حقوق = BaseSalary + (Sales * Commission / 100)
4. چندریختی: لیستی از Employee بسازید و حقوق همه را محاسبه کنید
csharp
abstract class Employee
{
public string Name { get; set; }
public int ID { get; set; }
public double BaseSalary { get; set; }
public Employee(string name, int id, double baseSalary)
{
Name = name;
ID = id;
BaseSalary = baseSalary;
}
public abstract double CalculateSalary();
public void ShowInfo()
{
Console.WriteLine($"{Name} (ID: {ID})");
Console.WriteLine($"Base Salary: {BaseSalary:C}");
Console.WriteLine($"Total Salary: {CalculateSalary():C}");
}
}
class Manager : Employee
{
public double Bonus { get; set; }
public Manager(string name, int id, double baseSalary, double bonus)
: base(name, id, baseSalary)
{
Bonus = bonus;
}
public override double CalculateSalary()
{
return BaseSalary + Bonus;
}
}
class SalesPerson : Employee
{
public double SalesAmount { get; set; }
public double CommissionPercent { get; set; }
public SalesPerson(string name, int id, double baseSalary, double sales, double commission)
: base(name, id, baseSalary)
{
SalesAmount = sales;
CommissionPercent = commission;
}
public override double CalculateSalary()
{
return BaseSalary + (SalesAmount * CommissionPercent / 100);
}
}
// برنامه اصلی
class Program
{
static void Main()
{
Employee[] employees = new Employee[3];
employees[0] = new Manager("Ali Mohammadi", 101, 8000000, 2000000);
employees[1] = new SalesPerson("Sara Ahmadi", 102, 5000000, 10000000, 5);
employees[2] = new Manager("Reza Karimi", 103, 9000000, 3000000);
foreach (Employee emp in employees)
{
emp.ShowInfo();
Console.WriteLine();
}
Console.WriteLine("Press Enter to exit...");
Console.ReadLine();
}
}
`--- 📌 جمعبندی درس نهم مفهوم کلیدواژه توضیح ارثبری : class Dog : Animal دسترسی به پدر base base.Method() متد قابل بازنویسی virtual public virtual void Method() بازنویسی متد override public override void Method() کلاس چکیده abstract abstract class MyClass متد چکیده abstract public abstract void Method(); غیرقابل ارثبری sealed sealed class MyClass --- 🧪 تمرین برای شما 1. کلاس Shape abstract بسازید با متدهای GetArea() و GetPerimeter() 2. کلاسهای Square، Triangle، Circle را بسازید 3. آرایهای از Shape بسازید و مساحت همه را محاسبه کنید --- اگر این درس را کامل فهمیدید، بگویید تا درس دهم (اینترفیسها) را شروع کنیم. سوالی بود بپرسید.
خیلی خوب، رسیدیم به درس دهم: اینترفیسها (Interface).
اینترفیس یکی از قدرتمندترین مفاهیم در سیشارپ است که به شما اجازه میدهد قراردادهای مشخصی بین کلاسها تعریف کنید.
یک پروژه جدید بسازید (dotnet new console) و کدها را همراه من بنویسید و اجرا کنید.
---
📘 درس دهم – اینترفیسها (Interface)
🎯 سرفصلها:
1. اینترفیس چیست؟
2. تفاوت اینترفیس با کلاس abstract
3. پیادهسازی اینترفیس
4. چندین اینترفیس در یک کلاس
5. اینترفیس به عنوان نوع داده
6. متدهای پیشفرض در اینترفیس (C# 8.0)
7. تمرین جامع
---
⏱️ قسمت 1: اینترفیس چیست؟
اینترفیس = یک قرارداد (Contract) که مشخص میکند کلاس چه کارهایی باید انجام دهد، اما نه چگونگی انجام آن.
csharp
// تعریف اینترفیس
interface IAnimal
{
void MakeSound(); // فقط تعریف، بدون بدنه
void Move();
}
// پیادهسازی اینترفیس در کلاس
class Dog : IAnimal
{
public void MakeSound()
{
Console.WriteLine("Woof! Woof!");
}
public void Move()
{
Console.WriteLine("Dog is running");
}
}
class Cat : IAnimal
{
public void MakeSound()
{
Console.WriteLine("Meow! Meow!");
}
public void Move()
{
Console.WriteLine("Cat is walking silently");
}
}
// استفاده
IAnimal myDog = new Dog();
IAnimal myCat = new Cat();
myDog.MakeSound(); // Woof! Woof!
myCat.MakeSound(); // Meow! Meow!
📌 قوانین اینترفیس:
· فقط امضای متدها را تعریف میکند (بدون بدنه)
· نمیتواند فیلد داشته باشد
· کلاس میتواند چندین اینترفیس را پیادهسازی کند
· همه متدهای اینترفیس باید در کلاس پیادهسازی شوند
---
⏱️ قسمت 2: تفاوت اینترفیس با کلاس abstract
ویژگی اینترفیس (Interface) کلاس Abstract
تعداد در ارثبری چندین تا فقط یک کلاس
بدنه متدها ندارد (قبلاً) میتواند داشته باشد
فیلدها ندارد میتواند داشته باشد
سازنده ندارد میتواند داشته باشد
سطح دسترسی implicit public هر سطحی
کاربرد قرارداد پایه مشترک با بعضی پیادهسازیها
csharp
// اینترفیس: فقط قرارداد
interface IPrinter
{
void Print();
}
// کلاس abstract: میتواند پیادهسازی داشته باشد
abstract class Animal
{
public string Name { get; set; } // فیلد دارد
public abstract void MakeSound(); // بدون پیادهسازی
public void Sleep() // با پیادهسازی
{
Console.WriteLine("Sleeping...");
}
}
---
⏱️ قسمت 3: نامگذاری اینترفیسها
قاعده طلایی: نام اینترفیسها با I بزرگ شروع میشود.
csharp
interface IRepository // ✅ درست
interface ILogger // ✅ درست
interface IConvertible // ✅ درست
interface Printable // ❌ (بدون I)
interface IPrintable // ✅
---
⏱️ قسمت 4: پیادهسازی چندین اینترفیس
یک کلاس میتواند چندین اینترفیس را پیادهسازی کند.
csharp
interface IMovable
{
void Move();
}
interface ISpeakable
{
void Speak();
}
interface IFlyable
{
void Fly();
}
// کلاس میتواند چند اینترفیس داشته باشد
class Bird : IMovable, ISpeakable, IFlyable
{
public void Move()
{
Console.WriteLine("Bird is moving");
}
public void Speak()
{
Console.WriteLine("Bird is chirping");
}
public void Fly()
{
Console.WriteLine("Bird is flying");
}
}
// استفاده
Bird bird = new Bird();
bird.Move();
bird.Speak();
bird.Fly();
---
⏱️ قسمت 5: اینترفیس به عنوان نوع داده
میتوانیم از اینترفیس به عنوان نوع متغیر استفاده کنیم.
`csharp interface IShape { double GetArea(); double GetPerimeter(); } class Circle : IShape { public double Radius { get; set; } public Circle(double radius) { Radius = radius; } public double GetArea() { return Math.PI * Radius * Radius; } public double GetPerimeter() { return 2 * Math.PI * Radius; } } class Rectangle : IShape { public double Width { get; set; } public double Height { get; set; } public Rectangle(double width, double height) { Width = width; Height = height; } public double GetArea() { return Width * Height; } public double GetPerimeter() { return 2 * (Width + Height); } }
// چندریختی با اینترفیس
IShape[] shapes = new IShape[3];
shapes[0] = new Circle(5);
shapes[1] = new Rectangle(4, 6);
shapes[2] = new Circle(3);
foreach (IShape shape in shapes)
{
Console.WriteLine($"Area: {shape.GetArea():F2}");
Console.WriteLine($"Perimeter: {shape.GetPerimeter():F2}");
Console.WriteLine();
}
---
⏱️ قسمت 6: مثال واقعی – سیستم پرداخت
csharp
// اینترفیس پرداخت
interface IPayment
{
void Pay(decimal amount);
string GetPaymentMethod();
}
// پیادهسازی با کارت اعتباری
class CreditCardPayment : IPayment
{
public string CardNumber { get; set; }
public CreditCardPayment(string cardNumber)
{
CardNumber = cardNumber;
}
public void Pay(decimal amount)
{
Console.WriteLine($"Paid {amount:C} using Credit Card ending with {CardNumber.Substring(CardNumber.Length - 4)}");
}
public string GetPaymentMethod()
{
return "Credit Card";
}
}
// پیادهسازی با پیپال
class PayPalPayment : IPayment
{
public string Email { get; set; }
public PayPalPayment(string email)
{
Email = email;
}
public void Pay(decimal amount)
{
Console.WriteLine($"Paid {amount:C} using PayPal account {Email}");
}
public string GetPaymentMethod()
{
return "PayPal";
}
}
// پیادهسازی با ارز دیجیتال
class CryptoPayment : IPayment
{
public string WalletAddress { get; set; }
public CryptoPayment(string walletAddress)
{
WalletAddress = walletAddress;
}
public void Pay(decimal amount)
{
Console.WriteLine($"Paid {amount:C} using Crypto wallet {WalletAddress.Substring(0, 6)}...");
}
public string GetPaymentMethod()
{
return "Cryptocurrency";
}
}
// سیستم پرداخت
class PaymentProcessor
{
public void ProcessPayment(IPayment payment, decimal amount)
{
Console.WriteLine($"Processing {payment.GetPaymentMethod()} payment...");
payment.Pay(amount);
Console.WriteLine("Payment completed!");
}
}
// استفاده
PaymentProcessor processor = new PaymentProcessor();
IPayment payment1 = new CreditCardPayment("1234-5678-9012-3456");
IPayment payment2 = new PayPalPayment("user@example.com");
IPayment payment3 = new CryptoPayment("1A2B3C4D5E6F");
processor.ProcessPayment(payment1, 150.50m);
Console.WriteLine();
processor.ProcessPayment(payment2, 75.25m);
Console.WriteLine();
processor.ProcessPayment(payment3, 200.00m);
---
⏱️ قسمت 7: متدهای پیشفرض در اینترفیس (C# 8.0+)
از C# 8.0 به بعد، میتوان در اینترفیس متد با بدنه (پیشفرض) داشت.
csharp
interface ILogger
{
void Log(string message); // باید پیادهسازی شود
// متد پیشفرض (اختیاری برای پیادهسازی)
void LogError(string error)
{
Console.WriteLine($"ERROR: {error}");
Log(error); // میتواند متد دیگر را صدا بزند
}
}
class FileLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine($"Writing to file: {message}");
}
// نیازی به پیادهسازی LogError نیست (پیشفرض دارد)
}
class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine($"Console: {message}");
}
// میتوان LogError را بازنویسی کرد
public void LogError(string error)
{
Console.WriteLine($"!!! CONSOLE ERROR: {error} !!!");
}
}
// استفاده
ILogger fileLog = new FileLogger();
ILogger consoleLog = new ConsoleLogger();
fileLog.LogError("File not found"); // از پیشفرض استفاده میکند
consoleLog.LogError("Network error"); // از پیادهسازی خودش استفاده میکند
---
✅ تمرین نهایی درس دهم
سیستم مدیریت کاربران با اینترفیس بسازید:
1. اینترفیس IUser با متدهای:
· string GetUsername()
· string GetRole()
· bool HasPermission(string permission)
2. کلاس Admin : IUser
3. کلاس RegularUser : IUser
4. کلاس Guest : IUser
csharp
using System;
using System.Collections.Generic;
interface IUser
{
string GetUsername();
string GetRole();
bool HasPermission(string permission);
}