ورود

View Full Version : عملگر instanceof



Sina.iRoid
شنبه 07 آذر 1394, 11:42 صبح
سلام. لطف کنید کد زیر و نگاه کنید:

کلاس RationalNumber:


public class RationalNumber {

int top;
int bottom;

// constructor
public RationalNumber(int top, int bottom) {
this.top = top;
this.bottom = bottom;
}

// equals method
public boolean equals(Object obj) {
if (obj instanceof RationalNumber) {
RationalNumber k = (RationalNumber)obj;
if (k.top * bottom - k.bottom * top == 0) {
return true;
} else {
return false;
}
} else {
return false;
}
}
}


کلاس اصلی:


public class MaiClass {


public static void main(String[] args) {

RationalNumber num1 = new RationalNumber(2, 3);
RationalNumber num2 = new RationalNumber(2, 3);

if (num1.equals(num2)) {
System.out.println("True");
} else {
System.out.println("False");
}
}
}


در مورد عملگر instanceof من اینطور خوندم که این عملگر مقایسه که آیا یک آبجکت از جنس اون کلاس هست یا نه. در اینجا این بررسی انجام شده که obj از جنس کلاس RationalNumber هست یا نه؟ که برنامه وقتی اجرا میشه این شرط درست هست. اما به کد زیر نگاه کنید:


public class MaiClass {


public static void main(String[] args) {

Object obj = new Object();

if (obj instanceof MaiClass) {
System.out.println("True");
} else {
System.out.println("False");
}
}
}




جواب False است. این به نظرم دقیقا همون کدیه که در کلاس RationalNumber پیاده سازی کردم که مقداره True برگشت داده شد اما اینجا False ه. نکتش چیه؟ چرا اینطوری میشه؟
ممنون میشم اگر راهنماییم کنید :)

ahmad.mo74
شنبه 07 آذر 1394, 15:48 عصر
سلام.

چرا باید True چاپ بشه؟
اصلا چرا obj باید از جنس MaiClass باشه؟؟

شما یه شی از روی کلاس Object ساختی، چه ربطی باید به MaiClass داشته باشه؟

Sina.iRoid
شنبه 07 آذر 1394, 16:52 عصر
سلام.

چرا باید True چاپ بشه؟
اصلا چرا obj باید از جنس MaiClass باشه؟؟

شما یه شی از روی کلاس Object ساختی، چه ربطی باید به MaiClass داشته باشه؟

شما کده اولی و نگاه کنید. داخل کلاس RationalNumber شی obj بررسی شده که از جنس اون کلاس (RationalNumber) هست یا نه. که در اون کد مقدار true برگشت داده میشه. من در کد پایین هم دقیقا همون کار و انجام دادم، اما مقدار false برگشت داده میشه.

ahmad.mo74
شنبه 07 آذر 1394, 20:29 عصر
من در کد پایین هم دقیقا همون کار و انجام دادم، اما مقدار false برگشت داده میشه.

نه خیر! دقیقا همون نیست.

توی کد اولی آبجکت از جنس RationalNumber رو به تابع equals فرستادی و شرط obj instanceof RationalNumber قطعا جوابش true هست.
ولی تو کد بعدی آبجکت از جنس Object هست و شرط obj instanceof MaiClass نباید هم true بشه.

نمیدونم چرا این فکر رو کردی که obj باید از جنس MaiClass باشه!!!

Sina.iRoid
شنبه 07 آذر 1394, 21:01 عصر
نه خیر! دقیقا همون نیست.

توی کد اولی آبجکت از جنس RationalNumber رو به تابع equals فرستادی و شرط obj instanceof RationalNumber قطعا جوابش true هست.
ولی تو کد بعدی آبجکت از جنس Object هست و شرط obj instanceof MaiClass نباید هم true بشه.

نمیدونم چرا این فکر رو کردی که obj باید از جنس MaiClass باشه!!!

شما در کد اول خط 13 و نگاه کنید. obj از روی کلاس Object تغریف شده.( پس از جنس کلاس Object هست دیگه نه؟).در کد پایین هم من دقیقا از روی کلاس Object یه شی ایجاد کردم. ولی نمی دونم چرا اینطوریه.
ممنون از راهنماییتون

ahmad.mo74
شنبه 07 آذر 1394, 21:12 عصر
ممنون از راهنماییتون


خواهش میکنم.

فهمیدم مشکلت کجاست. این مثالو ببین، بازم اگه سوالت برطرف نشد بگو.


public static void main(String[] args) {


Object obj;


obj = new Object();
System.out.println("obj = new Object()");
System.out.println(obj.getClass());
System.out.println("obj instanceof Object ? " + (obj instanceof Object));
System.out.println("obj instanceof RationalNumber ? " + (obj instanceof RationalNumber));
System.out.println("obj instanceof MaiClass ? " + (obj instanceof MaiClass));
System.out.println("********************");


obj = new RationalNumber();
System.out.println("obj = new RationalNumber()");
System.out.println(obj.getClass());
System.out.println("obj instanceof Object ? " + (obj instanceof Object));
System.out.println("obj instanceof RationalNumber ? " + (obj instanceof RationalNumber));
System.out.println("obj instanceof MaiClass ? " + (obj instanceof MaiClass));
System.out.println("********************");


obj = new MaiClass();
System.out.println("obj = new MaiClass()");
System.out.println(obj.getClass());
System.out.println("obj instanceof Object ? " + (obj instanceof Object));
System.out.println("obj instanceof RationalNumber ? " + (obj instanceof RationalNumber));
System.out.println("obj instanceof MaiClass ? " + (obj instanceof MaiClass));


}

Sina.iRoid
شنبه 07 آذر 1394, 21:38 عصر
ابتدا سپاس از قرار دادن این کد.
من دقیقا متوجه کدتون شدم. شما در هر سه حالت، از روی شی تعریف شده از روی کلاس Object، سه شی با جنس های (Object, RationalNumber, MainClass) مختلف ایجاد کردید.
اما در کد من در پارامتر متد equals، شی obj از روی کلاس Object فقط تعریف شده و جنس کلاس مشخص نشده. یعنی از کلمه کلیدی new برای ساخت آبجکت استفاده نشده. پس چطور از جنس کلاس RationalNumber شده.
شاید من با تمرین زیادتر بتونم این و متوجه بشم. به هر حال ممنون از راهنماییتون :)

ahmad.mo74
یک شنبه 08 آذر 1394, 12:49 عصر
وقتی یه آبجکتی رو از هر نوعی تولید کنی، اصالت خودش رو تو هر شرایطی حفظ می کنه. یعنی چی؟
یعنی اینکه مثلا وقتی آبجکتی از نوع RationalNumber رو به کلاس پدر خودش یعنی Object (یا هر کلاس دیگه ای که ازش extend شده) cast می کنی (اصطلاحا میگن up-casting)، بازم اون آبجکت از نوع RationalNumber هست و بعدا میتونی دوباره با cast کردن بهش برسی.

اینجا هم دقیقا همین موضوع تکرار شده. یعنی یه آبجکت از نوع RationalNumber ساختی و به متد equals فرستادیش. درسته نوع پارامتر ورودی اون تابع Object هست، اما بازم اون آبجکت instance ای از RationalNumber هست و با cast کردن بهش میرسی و گرنه موقع cast کردن باید خطا میداد که این آبجکت از نوع RationalNumber نیست و نمیشه بهش cast اش کرد.
گذاشتن شرط obj instanceof RationalNumber هم بخاطر همین هست که از رخ دادن اکسپشن جلوگیری بشه و مطمئن باشیم آبجکت از همون نوعی که می خوایم به دستمون رسیده.