تبلیغاتستان
مکانی برای تبلیغات شما
نوشته شده در تاريخ برچسب:, توسط مهدی |
کلاسهای (Abstract):
کلاسهای Abstract کلاسهایی هستند که دارای یک یا چند متد پیاده سازی نشده هستند.  اگر متدی رو به شکل abstract تعریف کردید، باید کلاس رو هم به شکل abstract تعریف کنید. بطور مثال یک کلاس پایه با نام Shape تعریف می کنیم که پارامترهایی رو نگهداری می کنه و یک شی Pen هم برای رسم می سازیم. متد draw برای رسم استفاده می شه و ما اون رو فقط تعریف می کنیم و کدی رو برای پیاده سازی اون نمی نویسیم، چون هر شکلی به روش رسم خاصی نیاز دارد. (زمانی از کلاسهای Abstract استفاده می کنیم که بخواهیم کلاس پایه ای داشته باشیم و متدهای اون در کلاسهای مشتق شده نیاز به بازنویسی داشته باشه) به لیست کد 1 دقت کنید:
// List Code 1
public abstract class Shape
{
protected int height, width;
protected int xpos, ypos;
protected Pen bPen;
//-----
public Shape(int x, int y, int h, int w)
{
width = w;
height = h;
xpos = x;
ypos = y;
bPen = new Pen(Color.Black);
}
//-----
public abstract void draw(Graphics g);
//-----
public virtual float getArea()
{
  return height * width;
}
}
توجه کنید که ما متد draw رو به شکل abstract تعریف کرده ایم و پس از تعریف با استفاده از ; انتهای تعریف متد را مشخص کرده ایم. کلاس تعریف شده نیز به شکل abstract تعریف شده است.
همچنین برای استفاده از کلاسهای abstract نیز باید از کلاسهای مشتق شده اون یک نمونه بگیرید و از کلاس abstract نمی توان یک نمونه ایجاد کرد. ادامه مسیر ساخت کلاس رو پی می گیریم و حالا باید کلاس Rectangle رو بسازیم. برای این منظور کلاس مورد نظر رو از کلاس Shape که به شکل Abstract تعریف شده مشتق می کنیم. به لیست کد 2 توجه فرمایید:

// List Code 2 (Rectangle class derived from abstract base class)
public class Rectangle:Shape
{
public Rectangle(int x, int y,int h, int w):base(x,y,h,w) {}
//-----
public override void draw(Graphics g)
{
  g.DrawRectangle (bPen, xpos, ypos, width, height);
}
}

کلاس Rectangle کلاسی است که می توانید از آن یک نمونه بگیرید. که یک متد draw واقعی دارد و می تواند رسم مستطیل را انجام دهد. برای مثال کلاس دومی رو هم پیاده سازی کرده ایم. به لیست کد 3 دقت نمایید که پیاده سازی کلاس Circle را نمایش می دهد.
// List Code 3 (Circle class derived from abstract base class)
public class Circle :Shape
{
public Circle(int x, int y, int r):base(x,y,r,r) {}
//-----
public override void draw(Graphics g)
{
  g.DrawEllipse (bPen, xpos, ypos, width, height);
}
}
حالا می خواهیم که بر اساس کلاس های تعریف شده، نمونه ای ایجاد کنیم. در لیست کد 4 نمونه های تعریف شده اند که پارمترهای مورد نیاز با استفاده از سازنده اون ارسال شده است.

// List Code 4
public class Form1 : System.Windows.Forms.Form
{
private PictureBox pictureBox1;
private Container components = null;
private Shape rect, circ;
//-----
public Form1()
{
  InitializeComponent();
  init();
}
//-----
private void init()
{
  rect = new CsharpPats.Rectangle (50, 60, 70, 100);
  circ = new Circle (100,60, 50);
}
}

در آخر، در رویداد Paint رسم دایره و مستطیل رو انجام می دهیم. به لیست کد 4 دقت نمایید که یک دایره و یک مستطیل رسم شده است.

// List Code 5
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics ;
rect.draw (g);
circ.draw (g);
}
تمرین: یک پروژه برای مثال این پست ساخته آن را برای رسم پنج ضلعی منتظم توسعه دهید.

مقایسه کلاسهای Abstract و کلاسهای Interface:
- زمانی که یک کلاس واسط Interface Class تعریف می کنیم، مجموعه ای از تعریف یک یا چند متد رو خواهیم داشت که باید برای هر کلاسی که از این واسط مشتق می شود کد نویسی شود. هیچ کدی اولیه ای برای کلاسها نوشته نخواهد شد. در این حالت شما یک ساختار درختی از وراثت کلاسها خواهید داشت که از کلاس پایه (کلاس واسط) نمی توان نمونه ای ایجاد کرد و اگر متدی از واسط رو در کلاس خارجی تعریف و کد نویسی نکنید حتما با خطای کامپایلر مواجه خواهید شد.
- زمانی که یک کلاس Abstract می سازید، شما یک کلاس پایه با تعریف یک یا چند متد دارید که ممکن است کد نویسی شده  یا نشده باشند و به شکل Abstract تعریف شده است. شما نمی توانید از یک کلاس Abstract نمونه بگیرید و البته می توانید از کلاس مشتق شده از کلاس Abstratct که متدهای اون پیاده سازی شده است، نمونه بگیرید. اگر همه متدهای تعریف شده در کلاس بدون کد باشند، این کلاس کاملا مشابه کلاسهای واسط خواهد بود با این محدودیت که نمی توانید از آن مانند کلاس واسط ساختار درختی وراثت را داشته باشید. بیشترین استفاده از کلاسهای Abstract فراهم نمودن تعریف کلاس پایه ای است برای کلاسهای مشتق شده ای که می خواهند کاری را انجام دهند و به برنامه نویس اجازه داده می شود که شخصا کدهای موردنیازش را در کلاسهای مشتق شده مختلفی پیاده سازی نماید. استفاده دیگر پیاده سازی متدهای خالی از کد است که ممکن است در کلاسهای مشتق شده دیگر پیاده سازی نشده باشند و بخواهید اطمینان داشته باشید که پروژه شما کامپایل خواهد شد.
به مثال زیر توجه نمایید (لیست کد 6):
// List Code 6
public class NullShape
{
protected int height, width;
protected int xpos, ypos;
protected Pen bPen;
//-----
public Shape(int x, int y, int h, int w)
{
width = w;
height = h;
xpos = x;
ypos = y;
bPen = new Pen(Color.Black );
}
//-----
public void draw(Graphics g){}
//-----
public virtual float getArea()
{
  return height * width;
}
}
در این مثال متد draw خالی رها شده و کدی برای آن نوشته نشده است و کلاس مشتق شده بدون مشکل کامپایل خواهد شد. و هیچ اشاره ای به اینکه این متد یک متد Abstract بازنویسی شده است نمی شود.

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