بازم سلام خدمت همه دوستان گراميم كه منو هيچ وقت در پاسخ به سوالاتم تنها نگذاشتند :
من يك فايل پيوست كردم كه مثالي درباره Object است . اما 3 سوال دارم :
1) در مقايسه p1 و p2 و p3 در اين برنامه ، بايد طبيعتا p1 با p3 برابر باشد اما در خروجي چيز ديگري را نشان مي دهد .
2) در مقايسه p1==p1 يك پيغام Warning نمايش داده مي شود (البته مهم نيست ) اما چرا ؟ مگر با ديگر مقايسه ها چه فرقي دارد ؟
3) در چاپ آخر بجاي نمايش p1 is : 10 20 چيز ديگري نمايش داده مي شود .
دوستان گرامي تا برنامه را دانلود و اجرا نكنيد متوجه اين Error ها نمي شويد !
اما لازم به ذكر است كه مثال كاملا ساده و جالب و رواني مي باشد .
من بالاي هر كدام از بخش هايي كه دچار مشكل شدم رو به صورت يك Comment نمايش داده ام .
بازم از تمام شما بزرگواران تشكر مي كنم .
اول یه نکته که احتمالا میدونید. ما دو نوع متغیر داریم. اصطلاح دقیقشون یادم نیست حالا من اسمشونو میگذارم مرجعی و مقداری. انواعی مثل int ها از نوع مقداری هستند. یعنی هرچی ازشون کپی کنیم توی یه مکان حافظه جداگانه مقدارشون کپی میشه. ولی اکثر کلاسها از جمله کلاسهای تعریفی کاربر از نوع مرجعی هستن. یعنی اگه کپی کنید ازشون فقط آدرس حافظه کپی میشه و نه مقدارشون. فکر کنم نمی خونید اینو بهتر بود
1- زیر 3 رو بخونید.
2- برای من warning نداد. الان داد. میگه مطمئنی اشتباه نکردی؟ منظورش اینه که کرم داری یه متغیر رو با خودش مقایسه میکنی؟

3- زیر رو بخونید.
ببینید. وقتی یه کلاس تعریف میکنید اگه کلاس مشخصی برای ارث بردن براش تعریف نکنید کلاستون از Object ارث میبره. و بنابر این 7 تا تابع اونو به ارث میبره. این توابع کار خاص خودشونو میکنن. مثل Equals که مساوی بودن رو چک میکنه و منظور از این مساوی بودن یکی بودن آدرسشونه و نه مقدارشون چون هنوز معلوم نیست کلاسی که ازش ارث میبره قراره چه مقادیری توی خودش نگه داره . در اصل کار چک کردن آدرس ها برای تابع ReferenceEquals هسته.
== هم به همچنین. این عملگر هم همونطوری که برای Object تعریف شده کار میکنه و فقط آدرس هاشونو مقایسه میکنه به همون دلیلی که گفتم.
و ToString هم به همچنین. این هم از Object ارث برده و صرفا کاری که براش تعریف شده رو انجام میده یعنی برگردوندن نوع کلاس.
توی کلاسهای دیگه دات نت که میبینید همین توابع کار دیگه ای میکنن اونجا ها خود کلاس ها اونا رو برای کار خودشون بازنویسی کردن.
حالا اگه میخواید اینا برای کلاس شما کار کنن باید خودتون اونا رو باز نویسی کنید برای کلاستون. یعنی یه عملگر == تعریف کنید که فقط مقادیر رو چک کنه. یه Equals که همون کار == رو بکنه. و یه ToString که مقدار دو تا متغیر درونی رو برگردونه.
یعنی کلاس شما میشه یه همچین چیزی:
نکته: تابع Equals اگه بازنویسی بشه باید تابع GetHashCode هم باز نویسی بشه. البته من GetHashCode رو کدی براش ننوشتم.
نکته2 : وقتی == بازنویسی میشه =! هم باید بازنویسی بشه. نگی کرم داری کد رو شلوغ میکنی.
کد php:
public class oldPoint
{
private int x,y;
public oldPoint(int x,int y)
{
setX(x);
setY(y);
}
public int getX()
{
return (x);
}
public int getY()
{
return (y);
}
public void setX(int newX)
{
x=newX;
}
public void setY(int newY)
{
y=newY;
}
//New Members:
// override object.ToString
public override string ToString()
{
return "{" + x + "," + y + "}";
}
// override object.Equals
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}
oldPoint p = (oldPoint)obj;
if ((p.x == x) && (p.y == y))
return true;
else
return false;
}
// override object.GetHashCode
public override int GetHashCode()
{
return base.GetHashCode();
}
// provide a new == operator for this object
public static bool operator ==(oldPoint p1, oldPoint p2)
{
if ((p1.x == p2.x) && (p1.y == p2.y))
return true;
else
return false;
}
// provide a new != operator for this object
public static bool operator !=(oldPoint p1, oldPoint p2)
{
if ((p1.x != p2.x) || (p1.y != p2.y))
return true;
else
return false;
}
}
حالا اینو بگذارید به جای اون کلاس. دقیقا کارایی که شما میخواید رو انجام میده.