کلاس ها در سی شارپ
کلاس ها ی abstract
کلاس ها را
همچنین می توان به صورت abstract
تعریف کرد. از این نوع کلاس ها نمی توان instance ایی را ایجاد نمود. در این کلاس های
پایه ، صرفا تعریف متدها و خواص هایی عنوان گردیده و در آینده در کلاس های
فرزند توسعه داده خواهند شد. برای مثال :
public abstract class
Named
{
public abstract String Name {get; set;} // property
public
abstract void PrintName(); // method
}
public class B : Named
{
private String name = "empty";
public override String Name
{
get{return name;}
set{name=value;}
}
public override
void PrintName()
{
Console.WriteLine("Name is {0}", name);
}
}
والی که شاید پیش بیاید این است که اگر interface ها صرفا تعریف توابع و خواص را می
توانند در خود جای دهند پس چه دلیلی برای بکار بردن آنها و طولانی کردن کار
کد نویسی وجود دارد؟
کاربردهای زیادی را می توان برای اینترفیس ها
برشمرد. اینترفیس یک رفتار را تعریف می کند. فرض کنید در حال توسعه ی
برنامه ایی هستید که بر روی دو کامپیوتر مختلف باید با هم در ارتباط مستقیم
بوده و برهم کنش داشته باشند و هر برنامه از ماژولی به نام CCommObj communication object
استفاده می نماید. یکی از متدهای این شیء ، SendData() می باشد که رشته ای را دریافت کرده و
به برنامه ی دیگر می فرستد. این فراخوانی از نوع asynchronous است زیرا ما نمی خواهیم اگر خطایی در
شبکه رخ داد، برنامه برای همیشه منتظر باقی بماند. اما چگونه برنامه ی A که تابع ذکر شده را فراخوانی کرده است
می تواند تشخیص دهد که پیغام به مقصد رسیده است یا خیر و یا آیا خطایی در
شبکه مانع رسیدن پیغام گشته است یا خیر؟ جواب بدین صورت است که CCommObj هنگام دریافت پیغام ، رخدادی را سبب
خواهد شد و اگر خطایی رخ داده باشد خیر. در این حالت نیاز به یک ماژول logging نیز احساس می گردد تا خطاهای رخ داده را
ثبت نماید. یک روش انجام آن این است که CCommObj پیاده سازی این امکان را نیز بعهده
گرفته و اگر فردا نیز خواستیم ماژول دیگری را به برنامه اضافه کنیم هر روز
باید CCommObj را تغییر
دهیم. تمام این کارها را به سادگی می توان در یک اینترفیس مدل کرد. روش آن
نیز در ادامه بیان می گردد:
در ابتدا یک اینترفیس ایجاد می کنیم تا
لیست تمام امکانات ممکن را "منتشر" کند:
interface ICommObjEvents
{
void OnDataSent();
void OnError();
}
شی ء CCommObj ما از این توابع که بعدا توسعه داده خواهند شد برای با خبر سازی کلاینت ها استفاده می نماید. تمام متدها در یک اینترفیس ذاتا پابلیک هستند بنابراین نیازی به ذکر صریح این مطلب نمی باشد و اگر اینکار را انجام دهید کامپایلر خطای زیر را گوشزد خواهد کرد :
The modifier 'public' is not valid for this item
در ادامه کلاینت CClientApp_A را پیاده سازی خواهیم کرد :
class
CClientApp_A:ICommObjEvents
{
public void OnDataSent()
{
Console.WriteLine("OnDataSent");
}
public void OnError()
{
Console.WriteLine("OnError");
}
private CCommObj m_Server;
public void Init(CCommObj
theSource)
{
m_Server = theSource;
theSource.Advise (this);
string
strAdd = ("N450:1");
m_Server.read (strAdd,10);
}
}
در کد فوق کلاس CClientApp_A از ICommObjEvents ارث برده و تمام متدهای این اینترفیس را
پیاده سازی نموده است. هنگامی که CCommObj تابع OnDataSent را فراخوانی می کند این کلاینت پیغام را
دریافت خواهد کرد. لازم به ذکر است که کلاس کلاینت ما چون از یک اینترفیس
ارث بری می نماید پس باید تمام توابع و خواص کلاس پایه را پیاده سازی کند
در غیر اینصورت هر چند برنامه کامپایل خواهد شد اما هنگامی که شیء CCommObj هر کدام از توابع این کلاس را فراخوانی
کد ، خطای زمان اجرا رخ خواهد داد.
متد Init
کلاس فوق آرگومانی را از نوع CCommObj
دریافت نموده و در یک متغیر private
آنرا ذخیره می نماید. همچنین در این متد ، متد Advise از کلاس CCommObj نیز فراخوانی گشته است.
public class CCommObj
{
private int m_nIndex;
public ICommObjEvents [ ] m_arSinkColl;
public
CCommObj()
{
m_arSinkColl = new ICommObjEvents[10];
m_nIndex
= 0;
}
public int Advise(ICommObjEvents theSink)
{
m_arSinkColl[m_nIndex]
= theSink;
int lCookie = m_nIndex;
m_nIndex++;
return
lCookie
}
public void SendData(string strData)
{
foreach
( ICommObjEvents theSink in m_arSinkColl)
if(theSink != null )
theSink.OnDataSent
();
}
}
- ۹۲/۰۱/۲۲