زنگ سی شارپ – قسمت بیست و چهارم

توضیحاتی در مورد کنترل دسترسی به اعضای کلاس و دو مثال برای درک بیشتر برنامه‌نویسی شی‌گرا و کدنویسی امن‌تر


مسعود درویشیان ۲۹ دیدگاه سی شارپ شنبه, ۷ام بهمن , ۱۳۹۱ 22755 بازدید

کنترل دسترسی به اعضای کلاس

Encapsulation در سی‌شارپ بدین معناست که اطلاعات یک کلاس در برابر دسترسی‌های غیرمجاز و خراب‌کاری محفوظ نگه داشته شود. کلاس که امکان encapsulation را به شما می‌دهد، دو مزیت عمده دیگر نیز به همراه دارد. اول اینکه داده‌ها را به کدهای درون کلاس متصل می‌کند. دوم اینکه دسترسی به اعضای کلاس را کنترل می‌کند. تا اینجا شما با دو نوع از اعضای کلاس آشنا شده‌اید که یکی public بود و دیگری private.

زنگ سی‌شارپ - قسمت بیستم و چهارم

عضوی که public است می‌تواند آزادانه در خارج از کلاس خودش نیز قابل دسترسی باشد. اعضای private فقط درون همان کلاس قابل دسترسی هستند و البته از طریق یک متد public می‌توانند قابل دسترسی و کنترل باشند.

محدود کردن دسترسی به اعضای یک کلاس یکی از بخش‌های اساسی برنامه‌نویسی شی‌گرا است چراکه از استفاده‌ی نادرست یک شیء جلوگیری می‌کند. کنترل دسترسی از طریق access modifier ها انجام می‌شود که public، private، protected و internal هستند. فعلاً به public و private می‌پردازیم و protected و internal در جای خود توضیح داده می‌شوند. استفاده به‌موقع و به‌جا از public و private یکی از نکات مهم و کلیدی برنامه‌نویسی شی‌گرا است. در زیر به چند نکته در این مورد اشاره شده:

  • آن دسته از اعضای کلاس که فقط در همان کلاس استفاده می‌شوند باید private باشند.
  • داده‌هایی که باید بین یک محدوده خاص باشند نیز باید private باشند و دسترسی به آن‌ها از طریق یک متد public که بازه‌ی اعداد را بررسی می‌کند، کنترل شود.
  • اگر تغییر دادن یکی از اعضا موجب شود که تاثیر این تغییر از آن عضو فراتر رود (و بر قسمت‌های دیگر شیء تاثیر گذارد)، آن عضو باید private باشد و دسترسی به آن باید کنترل شود.
  • آن دسته از اعضا که درصورت استفاده نادرست موجب می‌شوند که شیء آسیب ببینید و آن‌طور که باید رفتار نکند، باید private باشند و دسترسی به آن‌ها از طریق متدهای public انجام شود تا از استفاده‌ی نادرست آن‌ها جلوگیری شود.
  • متدهایی که مقداری را به اعضای private اختصاص می‌دهند یا مقدار آن‌ها را می‌خوانند، باید public باشند.
  • اگر هیچ دلیلی برای private کردن متغیرهای کلاس نیافتید، می‌توانید آن‌ها را public در نظر بگیرید.

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

برای این‌که درک بهتری از این موارد داشته باشید و بدانید که چرا و چگونه از این‌ها استفاده می‌کنیم، مثالی از ساختمان داده‌ی stack می‌تواند مفید باشد. یکی از مثال‌های مفید برنامه‌نویسی شی‌گرا کلاسی است که stack را پیاده‌سازی و اجرا می‌کند. همان‌طور که احتمالاً می‌دانید، stack ساختاری است برای ذخیره کردن اطلاعات که در آن اولین مقدار ذخیره شده، آخرین مقداری است که مورد استفاده قرار می‌گیرد. این‌طور تصور کنید که تعدادی ظرف را روی میزی (روی هم) قرار داده‌اید. اولین ظرفی که روی میز قرار دادید، آخرین ظرفی است که می‌توانید آن را بردارید یا برعکس، آخرین ظرفی که گذاشته‌اید، اولین ظرفی است که می‌توانید آن را بردارید. به این مکانیسم در اصطلاح Last-in, First-out می‌گویند. کلاسی که ما برای این منظور تعریف می‌کنیم شامل محلی برای ذخیره‌سازی اطلاعات و متدهایی برای کنترل روی این اطلاعات است بنابراین stack درواقع یک data engine است که این اجبار را به‌وجود می‌آورد تا عملیات Last-in, First-out اجرا شود. با این تعاریف نیاز است که یک‌سری از اعضای کلاس private و یک‌سری دیگر public باشند تا بتوان مکانیسم Last-in, First-out را اجرا کرد.

یک stack دو عملکرد پایه‌ای را انجام می‌دهد که عمل push و pop هستند. Push یک مقدار را به بالای stack اضافه می‌کند و pop یک مقدار را از بالای stack حذف می‌کند. کلاسی که تعریف خواهیم کرد، شامل یک آرایه‌ی private برای ذخیره سازی اطلاعات و دو متد public که عملیات pop و push را انجام می‌دهند و Last-in, First-out را پیاده می‌کنند:

// A stack class for characters
class Stack
{
    // These members are private
    char[] stck; // holds the stack
    int tos; // index of the top of the stack

    // Construct an empty Stack given its size.
    public Stack(int size)
    {
        stck = new char[size]; // allocate memory for stack
        tos = 0;
    }

    // Push characters onto the stack
    public void Push(char ch)
    {
        if (tos == stck.Length)
        {
            Console.WriteLine("Stack is full!");
            return;
        }
        stck[tos] = ch;
        tos++;
    }

    // Pop a character from the stack.
    public char Pop()
    {
        if (tos == 0)
        {
            Console.WriteLine("Stack is empty!");
            return (char)0;
        }
        tos--;
        return stck[tos];
    }

    // Return true if the stack is full.
    public bool IsFull()
    {
        return tos == stck.Length;
    }

    // Return true if the stack is empty.
    public bool IsEmpty()
    {
        return tos == 0;
    }

    // Return total capacity of the stack.
    public int Capacity() { return stck.Length; }

    // Return number of objects currently on the stack.
    public int GetNum() { return tos; }
}

بهتر است به این کلاس دقیق‌تر نگاه کنیم. کلاس Stack با تعریف این دو instance variables شروع می‌شود:

// These members are private
char[] stck; // holds the stack
int tos; // index of the top of the stack

آرایه‌ی stck محلی برای ذخیره‌سازی اطلاعات در stack فراهم می‌کند که این آرایه کاراکتر را در خود نگه می‌دارد. تخصیص آرایه توسط constructor انجام می‌گیرد و متغیر tos ایندکس (شماره) بالاترین خانه‌ی stack را در خود نگه می‌دارد.

هر دو عضو tos و stck به‌صورت private هستند و این باعث می‌شود که مکانیسم Last-in, First-out اجرا شود. اگر دسترسی این دو به‌صورت public تعریف شود آن‌گاه عناصر stack می‌توانند خارج از ترتیب قابل دسترسی باشند. همچنین از آن‌جا که متغیر tos ایندکس بالاترین عنصر stack را نگهداری می‌کند باید دسترسی به آن محدود شود تا توسط کدهای خارج از کلاس در دسترس و قابل دستکاری و خراب‌کاری نباشد. البته دسترسی به tos و stck از طریق متدهای public امکان‌پذیر است.

در خط بعد constructor را می‌بینید:

// Construct an empty Stack given its size.
public Stack(int size)
{
    stck = new char[size]; // allocate memory for stack
    tos = 0;
}

توسط constructor اندازه دل‌خواه stack مشخص شده و آرایه مورد نظر ساخته می‌شود. همچنین به متغیر tos مقدار صفر اختصاص می‌یابد. بنابراین مقدار صفر برای tos مشخص می‌کند که stack خالی است.

متد ()Push که public تعریف شده، یک عنصر را به stack اضافه می‌کند:

// Push characters onto the stack
public void Push(char ch)
{
    if (tos == stck.Length)
    {
        Console.WriteLine("Stack is full!");
        return;
    }
    stck[tos] = ch;
    tos++;
}

عنصری که قرار است به stack افزوده شود از طریق پارامتر ch وارد stack می‌شود. البته قبل از این‌که عنصری به stack اضافه شود ابتدا بررسی می‌شود که stack هنوز خانه‌ی خالی داشته باشد. این‌کار با بررسی این‌که tos از طول stck فراتر نرفته باشد انجام می‌شود. سپس کاراکتر در ایندکسی که tos مشخص می‌کند ذخیره می‌شود و در نهایت tos یک واحد افزایش می‌یابد. بنابراین tos همیشه ایندکس خانه‌ی بعدی stck را در خود نگه می‌دارد.

برای پاک کردن یک عنصر از stack از متد ()Pop استفاده می‌کنیم:

// Pop a character from the stack.
public char Pop()
{
    if (tos == 0)
    {
        Console.WriteLine("Stack is empty!");
        return (char)0;
    }
    tos--;
    return stck[tos];
}

در این‌جا مقدار tos بررسی می‌شود، اگر برابر با صفر بود stack خالی است در غیر این‌صورت tos یک واحد کاهش می‌یابد و عنصری که tos به آن اشاره می‌کند return می‌شود.

اگرچه ()Push و ()Pop تنها متدهایی هستند که برای اجرای یک stack مورد نیاز است اما تعریف چند متد دیگر نیز می‌تواند مفید باشد. ما در این کلاس ۴ متد بیشتر تعریف کرده‌ایم که ()IsFull()، IsEmpty()، Capacity و ()GetNum نام دارند و اطلاعاتی را از وضعیت stack به ما می‌دهند:

// Return true if the stack is full.
public bool IsFull()
{
    return tos == stck.Length;
}

// Return true if the stack is empty.
public bool IsEmpty()
{
    return tos == 0;
}

// Return total capacity of the stack.
public int Capacity() { return stck.Length; }

// Return number of objects currently on the stack.
public int GetNum() { return tos; }

متد ()IsFull هنگامی که stack پر است true برمی‌گرداند و متد ()IsEmpty هنگامی‌که stack خالی است true و هنگامی‌که stack خالی نیست false برمی‌گرداند. برای بدست آوردن ظرفیت کلی stack متد ()Capacity فراخوانی می‌شود و برای به‌دست آوردن تعداد عناصری که در stack ذخیره شده‌اند نیز از متد ()GetNum استفاده می‌شود. دلیل اهمیت این متدها این است که اطلاعات مورد نیاز برای دسترسی به tos را به ما می‌دهند (با این‌که private است). همچنین این متدها نمونه‌های خوبی هستند که بدانید چگونه از طریق متدهای public به اعضای private دسترسی و کنترل داشته باشید.

در مرحله‌ی بعد از این کلاس استفاده می‌کنیم:

using System;
class MyClass
{
    static void Main()
    {
        Stack stk1 = new Stack(10);
        Stack stk2 = new Stack(10);
        Stack stk3 = new Stack(10);
        char ch;
        int i;

        // Put some characters into stk1.
        Console.WriteLine("Push A through J onto stk1.");
        for (i = 0; !stk1.IsFull(); i++)
            stk1.Push((char)('A' + i));

        if (stk1.IsFull()) Console.WriteLine("stk1 is full.");

        // Display the contents of stk1.
        Console.Write("Contents of stk1: ");
        while (!stk1.IsEmpty())
        {
            ch = stk1.Pop();
            Console.Write(ch);
        }

        Console.WriteLine();

        if (stk1.IsEmpty()) Console.WriteLine("stk1 is empty.\n");

        // Put more characters into stk1.
        Console.WriteLine("Again push A through J onto stk1.");
        for (i = 0; !stk1.IsFull(); i++)
            stk1.Push((char)('A' + i));

        // Now, pop from stk1 and push the element in stk2.
        // This causes stk2 to hold the elements in reverse order.
        Console.WriteLine("Now, pop chars from stk1 and push " +
        "them onto stk2.");
        while (!stk1.IsEmpty())
        {
            ch = stk1.Pop();
            stk2.Push(ch);
        }

        Console.Write("Contents of stk2: ");
        while (!stk2.IsEmpty())
        {
            ch = stk2.Pop();
            Console.Write(ch);
        }
        Console.WriteLine("\n");

        // Put 5 characters into stack.
        Console.WriteLine("Put 5 characters on stk3.");
        for (i = 0; i < 5; i++)
            stk3.Push((char)('A' + i));

        Console.WriteLine("Capacity of stk3: " + stk3.Capacity());
        Console.WriteLine("Number of objects in stk3: " +
        stk3.GetNum());
    }
}

خروجی:

در مثال بعد قصد داریم برنامه دفترچه تلفن سابق را بیشتر شی‌گرا کنیم. در این دفترچه تلفن یک کلاس برای مخاطب داریم و یک کلاس برای دفترچه تلفن. در کلاس مخاطب، متغیرهای نام، آدرس و شماره تلفن قرار دارد. در کلاس دفترچه تلفن، متدهایی برای جستجو، افزودن مخاطب جدید و نمایش مخاطبان ذخیره شده وجود دارد:

using System;
class MainClass
{
    static void Main()
    {
        Phonebook myPhonebook = new Phonebook(5);
        while (true)
        {
            Console.Clear();
            Console.WriteLine("1. Add");
            Console.WriteLine("2. Search By Name");
            Console.WriteLine("3. Show all");
            Console.WriteLine("4. Exit");
            Console.WriteLine();
            Console.Write("Choose a number: ");
            string choice = Console.ReadLine();

            switch (choice)
            {
                case "1":
                    Console.Clear();
                    Person contact = new Person(
                        GetString("Please enter your name: "),
                        GetNum("Please enter your number: "),
                        GetString("Please enter your address: ")
                        );

                    if(myPhonebook.Add(contact))
                        Console.WriteLine("Your contact added successfully.");
                    else
                        Console.WriteLine("Fail!");

                    break;
                case "2":
                    myPhonebook.SearchByName(GetString("Please enter the name: "));
                    break;
                case "3":
                    Console.Clear();
                    myPhonebook.ShowContacts();
                    break;
                case "4":
                    Environment.Exit(0);
                    break;
                default:
                    Console.WriteLine("Invalid Input!");
                    break;
            }
            Console.ReadLine();
        }
    }
    static string GetString(string message)
    {
        Console.Write(message);
        return Console.ReadLine();
    }
    static int GetNum(string message)
    {
        Console.Write(message);
        return Convert.ToInt32(Console.ReadLine());
    }
}
class Person
{
    string Name;
    int Number;
    string Address;

    public Person(string name, int number, string address)
    {
        Name = name;
        Number = number;
        Address = address;
    }

    public string GetName() { return Name; }
    public int GetNumber() { return Number; }
    public string GetAddress() { return Address; }
}
class Phonebook
{
    Person[] Persons;
    int Current;
    bool Found;

    public Phonebook(int size)
    {
        Persons = new Person[size];
        Current = 0;
    }

    public bool Add(Person person)
    {
        if (Current < Persons.Length)
        {
            Persons[Current] = person;
            Current++;
            return true;
        }
        return false;
    }
    public void SearchByName(string search)
    {
        Found = false;
        for (int i = 0; i < Persons.Length; i++)
        {
            if (Persons[i] == null) break;
            if (search == Persons[i].GetName())
            {
                Found = true;
                Console.WriteLine();
                Console.WriteLine(Persons[i].GetName() + "\n" + Persons[i].GetNumber() +
                "\n" + Persons[i].GetAddress());
            }
        }
        if(!Found)
            Console.WriteLine("Not Found!");
    }
    public void ShowContacts()
    {
        for (int i = 0; i < Persons.Length; i++)
        {
            if (Persons[i] == null) return;
            Console.WriteLine(Persons[i].GetName() + "\n" + Persons[i].GetNumber() +
                "\n" + Persons[i].GetAddress() + "\n");
        }
    }
}

همان‌طور که می‌بینید نسبت به قبل از اشیاء و کلاس‌های بیشتری استفاده کردیم و این برنامه را بیشتر به سمت شی‌گرایی سوق دادیم.  در کلاس Person سه instance variable تعریف کرده‌ایم که هر سه private و شامل نام، آدرس و شماره تلفن هستند. همچنین از constructor برای مقداردهی به این سه متغیر استفاده کرده و از طریق متدهای public این متغیرها را Read-only کردیم. در کلاس Phonebook آرایه‌ای از جنس کلاس Person داریم. با این‌کار در هر خانه‌ی آرایه، یک شیء از جنس Person ذخیره می‌شود که شامل نام، آدرس و شماره تلفن است. از طریق constructor این کلاس، آرایه ساخته و مقدار دهی می‌شود. کلاس Phonebook همچنین شامل سه متد برای جستجو، افزودن مخاطب جدید و نمایش مخاطبان ذخیره شده دارد. همان‌طور که می‌بینید، متد ()Add یک شیء از جنس Person دریافت می‌کند و آن را در آرایه‌ای که از جنس Person ساخته بودیم ذخیره می‌کند و در نهایت اگر با موفقیت مخاطب جدید را ذخیره کرد، مقدار true را باز می‌گرداند. در متد ()Main برای افزودن مخاطب جدید، یک شیء از کلاس Person ساخته و argument های لازم را به آن داده‌ایم. سپس متد ()Add را صدا زده‌ایم تا مخاطب جدید ذخیره شود.



نویسنده / مترجم : مسعود درویشیان

علاقه مند به موسیقی و برنامه نویسی بازی


۲۹ دیدگاه برای این نوشته ثبت شده است


  1. داوود
    ۸ بهمن ۱۳۹۱

    سلام مسعود جان؛
    چه عجب!!!!!!!!!!!!!!!!!!
    ممنون برای گذاشتن قسمت بیست و چهارم.




  2. sami
    ۹ بهمن ۱۳۹۱

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




  3. داوود
    ۱۱ بهمن ۱۳۹۱

    سلام مجدد؛
    مسعود جان بحث stack یکم پیچیده است.
    میشه گفت که stack نوعی از آرایه است یا بالعکس ؟ آیا خود C# هم دستوراتی برای کار با stack داره یا نه؟
    در اینجا که شما گفتید Pop نقش پاک کردن رو برعهده داره یعنی چی؟
    من میخواستم که عناصری رو که الان تو stack3 قراردارن رو نمایش بدم و با این تکه کد این کار رو انجام دادم؛ درسته؟

    while (!stk3.IsEmpty())
    {
    ch = stk3.Pop();
    Console.Write(ch);
    }
    [/c#]
    پس چه زمانی این متد نقش پاک کردن stack رو اجرا میکنه؟در اینجا که من دارم ازش برای نمایش دادن استفاده می کنم.
    این تکه کد به چه معناست؟

    return (char)0;
    [/c#]
    ضمنا از نظر محل قرارگیری در حافظه میدونیم که متغیرهای مقداری در حافظه stack قرار می گیرن! آیا میشه مکان اونها رو تو حافظه دید؟
    و اینکه متغیرهای ارجاعی در heap ! درست میگم؟؟
    ببخشید از این همه سوال!




    • مسعود درویشیان
      ۲۱ بهمن ۱۳۹۱

      در اینجا متد ()Pop هم حذف می‌کنه هم آخرین خونه‌ی stack رو برمی‌گردونه (که می‌شه برای نمایش آخرین خونه stack ازش استفاده کرد)

      دستور return (char)0 هم وقتی که stack خالی هست اجرا می‌شه. چون این متد کاراکتر برمی‌گردونه باید قبلش عملیات cast رو انجام بدیم.

      ضمناً در مورد stack و heap توی مقالات آینده یه توضیح کامل می‌دم.




      • داوود
        ۲۱ بهمن ۱۳۹۱

        دستت درد نکنه مسعودجان؛ علیرغم این که اینروزها سرت شلوغه ولی ممنون که بازم جواب ما رو دادی.
        مرسی




  4. حمید
    ۱۳ بهمن ۱۳۹۱

    سلام
    خسته نباشید
    ممنون از آموزش ها
    ترتیب یک هفته ای درس به هم خورده؟




  5. مهدی
    ۱۳ بهمن ۱۳۹۱

    سلام آقای مهندس؛ احساس می کنم دیگه با علاقه مطالب رو نمیذارید! چرا؟ قرار نبود اینجوری بشه این مطالب درسی از این وبلاگ! ما دلمون به اینجا خوش بود.




    • مسعود درویشیان
      ۱۳ بهمن ۱۳۹۱

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




  6. نوید
    ۱۴ بهمن ۱۳۹۱

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




  7. f
    ۱۴ بهمن ۱۳۹۱

    سلام.امید وارم که حالتون خوب باشه.دوست عزیز با یادگرفتن این اموزش هایی که شما قرار می دید میشه خارج از محیط وب هم برنامه نوشت؟مثلا برای سیستم عامل اندروید.ممنون از سایت خوبتون.




    • مسعود درویشیان
      ۱۵ بهمن ۱۳۹۱

      سلام بله می‌تونید.




  8. حسين
    ۱۶ بهمن ۱۳۹۱

    باید یه تشکر ویژه بکنم از شما آقای درویشیان به خاطر زحماتی که میکشید.

    موفق باشی




  9. حمید
    ۲۰ بهمن ۱۳۹۱

    ما منتظریم. شماره بعدی رو کی میزارین؟




  10. ramazan
    ۶ اسفند ۱۳۹۱

    اگه امکان داره یه لینک برای دانلود تمام مطالب سی شارپ بذارید




    • مسعود درویشیان
      ۶ اسفند ۱۳۹۱

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




  11. محمد فر
    ۱۸ فروردین ۱۳۹۲

    سلام.
    منظور از این دستور چیه؟
    for (i = 0; !stk1.IsFull(); i++)
    stk1.Push((char)(‘A’ + i));
    شما در این حلقه برای شرط پایان حلقه مقدار بولی گذاشتید یعنی i از صفر شروع میشه تا مقدار بولی میره؟البته میدونم این حرفم اشتباه.میشه توضیح بدید؟




    • مسعود درویشیان
      ۱۸ فروردین ۱۳۹۲

      متد ()IsFull یه مقدار بولین برمی‌گردونه، حلقه تا زمانی اجرا می‌شه که این مقدار true باشه، به محض اینکه false برگرده برنامه از حلقه خارج می‌شه




  12. محمد فر
    ۱۸ فروردین ۱۳۹۲

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



    • توی حلقه ی for الزاما در قسمت شرط نباید دو عدد رو بررسی کنیم. البته این ظاهر شرط هست. ما شرط بررسی دو عدد رو که فلانی از فلانی کوچیکتر هست یا نه اینطوری برداشت میکنیم اگه کوچیه که هیچی اگه نه بیخیال. اما ماشین اینطوری میخونه که اون شرط یک مقدار درست یا نادرست داره. (پس ۱<2 درست بر میگردونه و اینجا !stk1.IsFull() هم درست یا نادرت برمیگردونه.) مثل هر حلقه ای وقتی شرط درست نباشه اجرا نمیشه. پس اینطوری به قضیه نگاه کنید که قسمت دوم چه عدد باشه یه تابع باید یک مقدار درست یا نادرست برگردونه.
      به عبارتی بله چیزی که شما متوجه شدید درسته. آفرین




  13. Mersad
    ۲۴ مرداد ۱۳۹۲

    سلام
    از آموزش های عالیتون بسیـــــــار متشکرم.

    شرمنده از اینکه خیلی سوال می پرسم.
    میخواستم بدونم ما با چه رویکردی باید کلاس ها رو طراحی کنیم؟
    منظورم اینه که ما در طراحی کلاس باید رویکردی کاملا شخصی داشته باشیم و اینجوری فکر کنیم قراره فقط خودمون از این کلاس استفاده کنیم و هرطور که با اون کلاس راحت تریم همونطور طراحیش کنیم، یا اینکه باید رویکرد عمومی داشته باشیم و این رو در نظر داشته باشیم که کسان دیگری هم ممکنه از این کلاس استفاده کن!
    این سوالم از این بابته که با این دو رویکرد، خیلی سخته که بفهمیم کدوم متغیر یا متدی رو چه زمانی private یا public تعریف کنیم.




    • مسعود درویشیان
      ۲۷ مرداد ۱۳۹۲

      هر کلاسی باید یه کار خاص رو انجام بده و باید سعی کنی موقع تعریف یه کلاس، دنیای وافعی در نظر بگیری!
      مثلاً یه انسان رو در نظر بگیر. دست یه کلاس اگر باشه، یه سری ویژگی‌ها و یه سری کار انجام می‌ده. اگر پا هم یه کلاس دیگه در نظر بگیری، اون هم یه سری ویژگی و کارهای خاص خودش رو داره. مثلاً اگر جمع شدن زانو رو یه متد در نظر بگیری، آیا این متد هیچ ربطی به کلاس دست داره؟ نه! private در نظر می‌گیریش ولی مثلاً یه فیلدی توی دست باشه که قراره از مغز فرمان بگیره، یا public در نظر می‌گیریش یا با یه متد کنترلش می‌کنی یا با property روش کنترل داری
      در کل طوری باشه اگه می‌دونی یه متد یا فیلد یا هر عضوی از کلاس با بیرون از کلاس نمی‌خواد ارتباطی داشته باشه، private بگیرش.
      باید حالت عمومی در نظر بگیرید که ازش سوء استفاده نشه




      • Mersad
        ۲۷ مرداد ۱۳۹۲

        متشکرم ازتون
        خیلی خوب توضیح دادین




  14. Mersad
    ۲۴ مرداد ۱۳۹۲

    یه سوال دیگه هم داشتم از خدمتتون

    میدونم که سوالم چندان در رابطه با موضوع درس نیست، ولی اگه امکانش براتون هست، یه توضیح مختصری راجع به data engine بدین لطفا.




  15. Mersad
    ۲۴ مرداد ۱۳۹۲

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

    میخواستم نظرتون رو بدونم در موردش، لطفا بیرحمانه انتقاد کنید!

     namespace WebTarget
    {
        class MyClass
        {
            static private PhoneBook myPhoneBook = new PhoneBook(3);
    
            static void Main()
            {
                Console.Clear();
    
                int select = Menu();
    
                Proccess(select);
    
    
    
                Console.ReadLine();
            }
    
            // Proccess
            static void Proccess(int choose)
            {
                Console.Clear();
                
                
                switch (choose)
                {
                    case 1:
                        string name, address;
                        int phoneNumber;
    
                        name = GetString("Enter Name : ");
                        phoneNumber = GetNum("Enter Phone Number : ");
                        address = GetString("Enter Address : ");
    
                        Person myPerson = new Person(name,phoneNumber,address);
    
                        if (myPhoneBook.Add(myPerson))
                            Console.WriteLine("Adding contacts to Success");
                        else
                            Console.WriteLine("Adding contacts has an error");
    
                        Console.ReadLine();
                        Main();
                        break;
    
                    case 2:
                        string searchName = GetString("Enter Search Name : ");
    
                        myPhoneBook.SearchByName(searchName);
    
                        Console.ReadLine();
                        Main();
                        break;
    
                    case 3:
                        int searchNum = GetNum("Enter Search Phone Number : ");
    
                        myPhoneBook.SearchByNumber(searchNum);
    
                        Console.ReadLine();
                        Main();
                        break;
    
                    case 4:
                        myPhoneBook.ShowAllContact();
    
                        Console.ReadLine();
                        Main();
                        break;
    
                    case 5:
                        Console.WriteLine("Thank You!");
                        Environment.Exit(0);
                        break;
    
                    default:
                        Console.WriteLine("Input Valid!");
                        Console.ReadLine();
                        Main();
                        break;
                }
            }
    
            //Menu's Method
            static int Menu()
            {
                Console.WriteLine("1. Add");
                Console.WriteLine("2. Search By Name");
                Console.WriteLine("3. Search By Phone Number");
                Console.WriteLine("4. Show All Contact");
                Console.WriteLine("5. Exit");
                Console.WriteLine();
                return GetNum("Please choose one of the options : ");
            }
    
            // GetString's Method
            static string GetString(string message)
            {
                Console.Write(message);
                return Console.ReadLine();
            }
    
            // GetNum's Method
            static int GetNum(string message)
            {
                Console.Write(message);
                return Convert.ToInt32(Console.ReadLine());
            }
        }
    
        // Person's Class
        class Person
        {
            private string Name;
            private int Number;
            private string Address;
    
            public Person(string name, int number, string address)
            {
                Name = name;
                Number = number;
                Address = address;
            }
    
            public string GetName() { return Name; }
            public int GetNumber() { return Number; }
            public string GetAddress() { return Address; }
        }
    
        // PhoneBook's Class
        class PhoneBook
        {
            // Fields
            private Person[] Persons;
            private int Current;
            private bool Found = false;
    
            // Constractor
            public PhoneBook(int size)
            {
                Persons = new Person[size];
                Current = 0;
            }
    
            //Add's Method
            public bool Add(Person person)
            {
                if (Current < Persons.Length)
                {
                    Persons[Current] = person;
                    Current++;
                    return true;
                }
                return false;
            }
    
            // Search By Name's Method
            public void SearchByName(string searchName)
            {
                for (int i = 0; i < Persons.Length; i++)
                {
                    if (searchName == Persons[i].GetName())
                    {
                        Found = true;
                        Console.WriteLine();
                        Console.WriteLine(Persons[i].GetName() + "\n" + Persons[i].GetNumber() +
                            "\n" + Persons[i].GetAddress());
                    }
                }
                if (Found == false)
                    Console.WriteLine("Not Found This Name!");
    
                Found = false;
            }
    
            // Search By Number's Method
            public void SearchByNumber(int searchNumber)
            {
                for (int i = 0; i < Persons.Length; i++)
                {
                    if (searchNumber == Persons[i].GetNumber())
                    {
                        Found = true;
                        Console.WriteLine();
                        Console.WriteLine(Persons[i].GetName() + "\n" + Persons[i].GetNumber() +
                            "\n" + Persons[i].GetAddress());
                    }
                }
                if (Found == false)
                    Console.WriteLine("Not Found This Number!");
    
                Found = false;
            }
    
            // Show All Contact's Method
            public void ShowAllContact()
            {
                Console.WriteLine("Name \t Number \t Address" + "\n");
    
                for (int i = 0; i < Persons.Length; i++)
                {
                    Console.WriteLine(Persons[i].GetName() + "\t" + Persons[i].GetNumber() +
                        "\t" + Persons[i].GetAddress());
                }
            }
    
        }
    
    }
     



  16. محمد
    ۹ شهریور ۱۳۹۳

    یه سوال در مورد مثال آخر آیا وقتی یک ر میزنیم و اد فرا خوانی می شه هر بار یک شی ساخته می شه و اون رو تو ماتریس ذخیره می کنه و دوباره که اد رو فراخوانی می کنیم دوباره با همون نام می سازه و استفاده می کنه؟
    و آیا دوباره که می سازه قبلی پاک نمی شه و فقط ریفرنس ولیو عوض می شه؟؟؟
    و این که این خط
    Person[] Persons;
    دقیقا چی کار می کنه ؟؟؟این چجور آرایه ایه ؟؟؟ تایپش چیه؟؟؟
    می شه ماتریسی ساخت که شی هایی از کلاس های مختلف بگیره؟؟؟ چرا اینارو توضیح ندادین؟




  17. esysss
    ۱۰ شهریور ۱۳۹۳

    /*******************************
    * esysss *
    ******************************/
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    class person
    {
    string Name;
    string Number;
    string Adress;
    public person(string name, string number, string adress)
    {
    Name = name;
    Adress = adress;
    Number = number;
    }
    public string getname()
    {
    return Name;
    }
    public string getnumber()
    {
    return Number;
    }
    public string getadress()
    {
    return Adress;
    }
    }
    class phonebook
    {
    person[] persons;
    int current;
    bool found;
    public phonebook(int size)
    {
    persons = new person[size];
    current = 0;
    }
    public bool add(person person)
    {
    if (current < persons.Length)
    {
    persons[current] = person;
    current++;
    return true;
    }
    return false;
    }
    public void searchbyname(string search)
    {
    found = false;
    for (int i = 0; i < persons.Length; i++)
    {
    if (persons[i] == null)
    break;
    if (search == persons[i].getname())
    {
    found = true;
    Console.WriteLine("OK\nwe found it\n\nname : " + persons[i].getname() + "\tnumber : " + persons[i].getnumber() + "\tadress : " + persons[i].getadress());

    }
    }
    if (!found)
    Console.WriteLine("sorry!!!\nnot found");
    }
    public void showcontacts()
    {
    for (int i = 0; i < current; i++)
    {
    if (persons[i].getadress() == null)
    break;
    Console.WriteLine("\n\n" + persons[i].getname() + "\n" + persons[i].getnumber() + "\n" + persons[i].getadress());
    }
    }

    }
    class program
    {
    static void Main()
    {
    phonebook myphonebooke = new phonebook(1000);
    while (true)
    {
    Console.Clear();
    Console.WriteLine();
    Console.WriteLine(" ***********************************");
    Console.WriteLine(" * welcome to my new phonebook *");
    Console.WriteLine(" * it's awsome *");
    Console.WriteLine(" * *");
    Console.WriteLine(" * 1-add *");
    Console.WriteLine(" * 2-search by name *");
    Console.WriteLine(" * 3-show all *");
    Console.WriteLine(" * 4-exit *");
    Console.WriteLine(" ***********************************");
    Console.WriteLine();
    Console.WriteLine();
    Console.WriteLine("choose a number : ");
    string choose = Console.ReadLine();
    switch (choose)
    {
    case "1":
    Console.Clear();
    person contact = new person(getstring("enter name : "), getstring("enter phone number : "), getstring("enter adress : "));
    if (myphonebooke.add(contact))
    Console.WriteLine("add sucessfully!!!!!!!!!!");
    else
    Console.WriteLine("fail");
    break;
    case "2":
    Console.Clear();
    myphonebooke.searchbyname(getstring("enter your name to search : "));
    break;
    case "3":
    myphonebooke.showcontacts();
    break;
    case "4":
    Console.ForegroundColor = ConsoleColor.Red;
    Console.WriteLine("thanks for using\nsee you again\n\nesysss");
    Console.ReadKey();
    Environment.Exit(0);

    break;
    default:
    Console.WriteLine("please enter right");

    break;
    }
    Console.ReadKey();
    }
    }
    static string getstring(string message)
    {
    Console.WriteLine(message);
    return Console.ReadLine();
    }
    }




  18. محسن
    ۶ آبان ۱۳۹۳

    من قصد نوشتن برنامه حسابداری با سی شارپ رو دارم لطفا راهنمایی بفرمایید.



دیدگاه خود را بنویسید





نشانی ایمیل شما منتشر نخواهد شد.

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

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

شما میتوانید با مراجعه به سایت گراواتار یک آواتار اختصاصی برای خود تعریف کنید، تا در کنار نام شما نمایش داده شود

برای قرار دادن کدهای نمونه می توانید از تگ های [php] ، [html] ، [css] و [js] استفاده کنید.
به عنوان مثال کدهای php را می توان به صورت زیر قرار داد:
[php] var $whoLoveIranians = "WebTarget!"; [/php]



کلیه حقوق مادی و معنوی برای وب سایت وب تارگت محفوظ است ©2017 وب‌تارگت

استفاده از مطالب وب سایت در سایر وب سایت‌ها و نشریات چاپی با ذکر منبع آزاد است.