نمایش نتایج 1 تا 11 از 11

نام تاپیک: نکات فنی در شی گرایی

  1. #1
    کاربر دائمی آواتار fazel-d
    تاریخ عضویت
    آذر 1386
    محل زندگی
    بورکینافاسو
    پست
    399

    Post نکات فنی در شی گرایی

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

    سوال اولم اینه که Interface ها چی هستند و کاربرد آنها در کجاست؟
    2- چه زمانی از کلمه کلیدی Virtual ، Static ، Sealed استفاده می شه؟
    از دوستانی که خارج از سوالات پرسیده شده ، نکاتی را هم از شی گرایی ارسال می کنند ، کمال تشکر را دارم. چرا که تقاضا دارم این تایپیک صرفا جهت پاسخ به سوالات نباشد.

  2. #2
    کاربر تازه وارد آواتار Sociant
    تاریخ عضویت
    آبان 1387
    محل زندگی
    اراک
    پست
    88

    نقل قول: نکات فنی در شی گرایی

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

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

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

    ...

  3. #3
    کاربر دائمی آواتار fazel-d
    تاریخ عضویت
    آذر 1386
    محل زندگی
    بورکینافاسو
    پست
    399

    Interface

    interface ها ساختارهایی شبيه كلاسها هستند و مانند کلاسها شامل property, method, indexer, event میباشند. ولي با اين تفاوت كه اين اجزا بصورت abstract در اينترفيس قرار ميگيرند نه بصورت concrete. يعني اين اجزا بدون بدنه در اينترفيس تعريف ميشوند.

    از طريق اينترفيس شما ميتوانيد يك كلاس را مجبور كنيد كه از قانوني خاص تبعيت كند. چگونه؟؟ از طريق اجزا (member) هايي كه در اينترفيس تعريف ميكنيد؛ و آن كلاس را مجبور ميكنيد كه اين اجزا را حتماً پياده سازي كند.
     interface IShape
    {
    string Name { get; }
    double GetArea();
    double GetPerimeter();
    }

    class Circle : IShape
    {
    private double _radius;
    public double Radius
    {
    get { return _radius; }
    set { _radius = value; }
    }

    public string Name
    {
    get { return "Circle"; }
    }

    public double GetArea()
    {
    return this._radius * this._radius * Math.PI;
    }

    public double GetPerimeter()
    {
    return this._radius * 2 * Math.PI;
    }
    }
    در اينجا از طريق اينترفيس IShape، كلاس Circle رو مجبور كرديم كه اجزاي اين اينترفيس را پياده سازي كند. اگر در اين كلاس اين دو متد و پروپرتي Name وجود نداشته باشد كامپايلر به شما خطا ميدهد.

    حالا اين اجبار به چه درد ميخورد؟ چه استفاده اي از آن ميشود؟ استفاده از اينترفيسها را interface polymorphism ميگويند. يعني پلي مرفيسم ار طريق اينترفيس. نوع ديگري پلي مرفيسم داريم كه به آن inheritance polymorphism ميگويند كه با آن كاري نداريم.

    پلي مرفيسم به چه دردي ميخورد؟ از طريق پلي مرفيسم شما ميتونيد يك عمل را براي طيف خاصي از كلاسها، عمومي (General) كنيد. يعني چه؟ يعني فقط يكبار يك عمل خاص بنويسيد و براي "چند كلاس هم خانواده" از آن استفاده كنيد و به اصطلاح از كد خود "فاكتور گيري" كنيد. پلي مرفيسم يعني اينكه يك شيء‌ رفتار متفاوت از خود نشان دهد. چطوري؟ در پست بعدي به آن خواهيم پرداخت.
    منبع: DotNetSource.Com
    با تشکر از حمید قادری

  4. #4
    کاربر دائمی آواتار fazel-d
    تاریخ عضویت
    آذر 1386
    محل زندگی
    بورکینافاسو
    پست
    399

    Interface

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

    حالا مثال رو کامل میکنیم و کلاس مستطیل (Rectangle) رو اضافه میکنیم
    class Rectangle : IShape
    {
    private double _width;
    public double Width
    {
    get { return _width;}
    set { _width = value;}
    }

    private double _height;
    public double Height
    {
    get { return _height;}
    set { _height = value;}
    }

    public string Name
    {
    get { return "Rectangle"; }
    }

    public double GetArea()
    {
    return this._width * this._height;
    }

    public double GetPerimeter()
    {
    return (this._width + this._height) * 2;
    }
    }
    خب پس دو کلاس Circle و Rectangle رو نوشتیم و اینترفیس IShape رو اصطلاحاً در آنها implement کردیم. حالا این دو کلاس 2 متد و یک پروپرتی یکسان دارند ولی با بدنه متفاوت و پیاده سازیهای مختلف.

    interface polymorphism چه شد؟
    خب حالا یک مساله: میخواهیم متدی بنویسیم که در ورودی یک شکل هندسی بگیرد و مشخصات آن را چاپ کند. بدون استفاده از اینترفیس مجبوریم برای هر شکل یک متد مجزا بنویسیم.
    private void DisplayCircleInfo(Circle  c)
    {
    Console.WriteLine("Shape Name: " + c.Name);
    Console.WriteLine("Shape Area: " + c.GetArea());
    Console.WriteLine("Shape Perimeter: " + c.GetPerimeter());
    }

    private void DisplayRectangleInfo(Rectangle r)
    {
    Console.WriteLine("Shape Name: " + r.Name);
    Console.WriteLine("Shape Area: " + r.GetArea());
    Console.WriteLine("Shape Perimeter: " + r.GetPerimeter());
    }
    وقتی اینترفیس نداریم از روش بالا استفاده میکنیم. اما از طریق اینترفیس میتوان کد بالا را یکی کرد!
    private void DisplayInfo(IShape  shape)
    {
    Console.WriteLine("Shape Name: " + shape.Name);
    Console.WriteLine("Shape Area: " + shape.GetArea());
    Console.WriteLine("Shape Perimeter: " + shape.GetPerimeter());
    }
    مگر میشود هم شیء Circle و هم شیء Rectangle به این متد پاس کرد؟ بله! چون هم Circle و هم Rectangle خود نوعی IShape هستند و در تعریف کلاسها با عملگر : این اینترفیس را پیاده سازی کردیم. بنابراین با این متد میتوان اطلاعات هر شیئی را که از اینترفیس IShape پشتیبانی میکند چاپ کرد.
    Circle c = new Circle();
    c.Radius = 3;
    DisplayInfo(c);

    Rectangle r = new Rectangle();
    r.Width = 5;
    r.Height = 4;
    DisplayInfo(r);
    بنابراین تا اینجا ما از کد خود فاکتور گیری کردیم و برای چاپ از یک متد استفاده کردیم. اما کجای کد ما پلی مرفیک است؟ کدام شیء رفتار متفاوت دارد؟ در متد آخر (DisplayInfo) شیء shape دارای رفتارهای متفاوت است! چون اگر Circle باشد یک تکه کد از کلاس Circle اجرا میشود و اگر Rectangle باشد یک تکه کد دیگر از کلاس Rectangle!!! (میتوان با گذاشتن break point و trace برنامه به این موضوع پی برد)


    منبع: DotNetSource.Com
    با تشکر از حمید قادری

  5. #5
    کاربر دائمی آواتار fazel-d
    تاریخ عضویت
    آذر 1386
    محل زندگی
    بورکینافاسو
    پست
    399

    نقل قول: نکات فنی در شی گرایی

    چه زمانی از کلمه کلیدی Virtual ، Static ، Sealed استفاده می شه؟
    یه سوال دیگه: [یه مقداری مثالا SATAthread] چیه که بالای یه کلاس یا متد ، اگه اشتباه نکنم میارن . امیدوارم منظورم را رسانده باشم.

  6. #6
    کاربر دائمی آواتار fazel-d
    تاریخ عضویت
    آذر 1386
    محل زندگی
    بورکینافاسو
    پست
    399

    Exclamation Sealed Modifier

    همان طور که از اسمش پیداست به معنی تغییر دهنده مهرو موم شده است.
    خوب این خاصیت به ما این امکان رو میده که از ارث بری ازکلاس ما یا از Override کردن متدهای ما جلوگیری کند.
    به عنوان مثال: کلاس B از کلاس A ارث برده است. ولی هیچ کلاسی نمی تواند از کلاس B ارث برد.
        class A {}    
    sealed class B : A {}


    مثال 2 در مورد توابع:
        class A
    {
    protected virtual void F() { Console.WriteLine("A.F");}
    protected virtual void F2() { Console.WriteLine("A.F2");}
    }
    class B : A
    {
    sealed protected override void F() { Console.WriteLine("B.F");}
    protected override void F2() {Console.WriteLine("A.F3");}
    }
    class C : B
    {
    // Attempting to override F causes compiler error CS0239.
    // protected override void F() { Console.WriteLine("C.F"); }

    // Overriding F2 is allowed.
    protected override void F2() { Console.WriteLine("C.F2"); }
    }

    Cاز B ارث می برد.اما C نمی تواند از تابع مجازی F که در A تعریف شده و در B ، مهرو موم شده استفاده کند.

    منبع MSDN
    خوب چه زمانی خوبه که از Sealed Modifier استفاده بشه؟

  7. #7
    کاربر دائمی آواتار fazel-d
    تاریخ عضویت
    آذر 1386
    محل زندگی
    بورکینافاسو
    پست
    399

    Virtual و Override

    اما موضوعی که بسیار در کلاسهای پایه ای خوده DotNet دیده می شه اینه که می شه برخی از توابع موجود رو سربارگذاری کرد و اجرای اون تابع را به دلخواه خود در آورد. مانند تابع OnPaint
    خوب برای override کردن هم باید تابع در کلاس پایه به صورت Modifier ای از virtual نوشته بشه

  8. #8

    نقل قول: Interface

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

    حالا مثال رو کامل میکنیم و کلاس مستطیل (Rectangle) رو اضافه میکنیم
    class Rectangle : IShape
    {
    private double _width;
    public double Width
    {
    get { return _width;}
    set { _width = value;}
    }

    private double _height;
    public double Height
    {
    get { return _height;}
    set { _height = value;}
    }

    public string Name
    {
    get { return "Rectangle"; }
    }

    public double GetArea()
    {
    return this._width * this._height;
    }

    public double GetPerimeter()
    {
    return (this._width + this._height) * 2;
    }
    }
    خب پس دو کلاس Circle و Rectangle رو نوشتیم و اینترفیس IShape رو اصطلاحاً در آنها implement کردیم. حالا این دو کلاس 2 متد و یک پروپرتی یکسان دارند ولی با بدنه متفاوت و پیاده سازیهای مختلف.

    interface polymorphism چه شد؟
    خب حالا یک مساله: میخواهیم متدی بنویسیم که در ورودی یک شکل هندسی بگیرد و مشخصات آن را چاپ کند. بدون استفاده از اینترفیس مجبوریم برای هر شکل یک متد مجزا بنویسیم.
    private void DisplayCircleInfo(Circle  c)
    {
    Console.WriteLine("Shape Name: " + c.Name);
    Console.WriteLine("Shape Area: " + c.GetArea());
    Console.WriteLine("Shape Perimeter: " + c.GetPerimeter());
    }

    private void DisplayRectangleInfo(Rectangle r)
    {
    Console.WriteLine("Shape Name: " + r.Name);
    Console.WriteLine("Shape Area: " + r.GetArea());
    Console.WriteLine("Shape Perimeter: " + r.GetPerimeter());
    }
    وقتی اینترفیس نداریم از روش بالا استفاده میکنیم. اما از طریق اینترفیس میتوان کد بالا را یکی کرد!
    private void DisplayInfo(IShape  shape)
    {
    Console.WriteLine("Shape Name: " + shape.Name);
    Console.WriteLine("Shape Area: " + shape.GetArea());
    Console.WriteLine("Shape Perimeter: " + shape.GetPerimeter());
    }
    مگر میشود هم شیء Circle و هم شیء Rectangle به این متد پاس کرد؟ بله! چون هم Circle و هم Rectangle خود نوعی IShape هستند و در تعریف کلاسها با عملگر : این اینترفیس را پیاده سازی کردیم. بنابراین با این متد میتوان اطلاعات هر شیئی را که از اینترفیس IShape پشتیبانی میکند چاپ کرد.
    Circle c = new Circle();
    c.Radius = 3;
    DisplayInfo(c);

    Rectangle r = new Rectangle();
    r.Width = 5;
    r.Height = 4;
    DisplayInfo(r);
    بنابراین تا اینجا ما از کد خود فاکتور گیری کردیم و برای چاپ از یک متد استفاده کردیم. اما کجای کد ما پلی مرفیک است؟ کدام شیء رفتار متفاوت دارد؟ در متد آخر (DisplayInfo) شیء shape دارای رفتارهای متفاوت است! چون اگر Circle باشد یک تکه کد از کلاس Circle اجرا میشود و اگر Rectangle باشد یک تکه کد دیگر از کلاس Rectangle!!! (میتوان با گذاشتن break point و trace برنامه به این موضوع پی برد)


    منبع: DotNetSource.Com
    با تشکر از حمید قادری
    سلام آقا فاضل
    متد private void DisplayInfo(IShape shape) کجا پیاده سازی می شود؟ مگه نفرمودید اینترفیس ها پیاده سازی ندارند؟ اگر هم خود کلاس دایره و مستطیل بایستی این متد را پیاده سازی کنند هر چند که بدنه دو متد یکسان است اما در هر دو کلاس باید این بدنه را نوشت؟ یا اینکه من تصور اشتباهی دارم
    ممنون

  9. #9
    کاربر تازه وارد آواتار gh-reza
    تاریخ عضویت
    خرداد 1388
    محل زندگی
    تبریز
    پست
    72

    نقل قول: نکات فنی در شی گرایی

    اگه یه متغیر یا متد متعلق به کلاس static تعریف بشه یعنی به ازای کلاس یک نمونه از اون وجود خواهد داشت. دسترسی به اون متغیر یا متد هم از طریق نام کلاس خواهد بود نه اشیاء درست شده از اون کلاس. مثلا Math.Sin بدون تعریف شیءای از نوع کلاس Math و فقط با نام کلاس فراخوانی میشه. یکی از متدهای static متد Main هست که چون از بیرون از C#‎ فراخوانی میشه (یعنی زمانی که هنوز هیچ شیءای بوجود نیومده) باید static باشه.

  10. #10
    کاربر دائمی آواتار fazel-d
    تاریخ عضویت
    آذر 1386
    محل زندگی
    بورکینافاسو
    پست
    399

    نقل قول: نکات فنی در شی گرایی

    در پیرو سوال زیر
    تد private void DisplayInfo(IShape shape) کجا پیاده سازی می شود؟ مگه نفرمودید اینترفیس ها پیاده سازی ندارند؟ اگر هم خود کلاس دایره و مستطیل بایستی این متد را پیاده سازی کنند هر چند که بدنه دو متد یکسان است اما در هر دو کلاس باید این بدنه را نوشت؟ یا اینکه من تصور اشتباهی دارم
    باید گفت که :
    Interface ها همانند کلاس ها تعریف شده و در جلوی نام کلاس ها با علامت : به ارث برده می شوند.
    نکته: هر کلاس تنها، از یک کلاس دیگر و از چندین Interface می تواند ارث ببرد. (محدودیت در ارث بری کلاسها)

    اینکه کجا متد DisplayInfo(IShape shape نوشته می شه ؟ در کلاس والد. مثلا form1.cs. ونیازی به override کردن ایم متد در کلاس دایره و ... نیست.

  11. #11
    کاربر دائمی آواتار mdssoft
    تاریخ عضویت
    خرداد 1386
    محل زندگی
    تهران / ساری
    پست
    392

    نقل قول: نکات فنی در شی گرایی

    ممنون از توضیحات خوبتون.

    اینکه کجا متد DisplayInfo(IShape shape نوشته می شه ؟ در کلاس والد. مثلا form1.cs. ونیازی به override کردن ایم متد در کلاس دایره و ... نیست.
    میشه یه نمونه کد بزارید ! من درست متوجه نشدم.

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •