روز بخیر مرد جوارش من شروع به دریافت سوالاتی در مورد انواع مرجع ریخته گری در جاوا کردم. برای اینکه هر بار یک چیز را تکرار نکنم، تصمیم گرفتم یک مقاله کوتاه بنویسم.
ابتدا بیایید ببینیم که ریخته گری چیست.
ریخته گری نوع (تبدیل نوع) تبدیل یک مقدار متغیر از یک نوع به مقداری از نوع دیگر است. بیایید به یک مثال نگاه کنیم که چه چیزی است و با چه چیزی خورده می شود. ما مقداری سلسله مراتب کلاس داریم ( شکل 1 را ببینید ). در اینجا میتوانید تمام کلاسهای سلسله مراتب را ببینید، چه کسی چه کسی را به ارث میبرد و متدهای هر کلاس. یک کشش در حال گسترش و انقباض وجود دارد. می بینیم که این کلاسCat
از نسل آن طبقه است Pet
. Pet
، به نوبه خود، جانشین کلاس است Animal
. وقتی می نویسیم:
Animal animalCat = new Cat();
Animal animalDog = new YorkshireTerrier();
این یک بازیگر در حال گسترش (یا یک بازیگر ضمنی) است. ما لینک ها را گسترش داده ایم animalCat
و animalDog
. اشاره به اشیا Cat
و Dog
. با چنین بازیگری، نمیتوانیم animalCat/animalDog
متدهایی را از طریق مرجعی فراخوانی کنیم که در هستند Cat/Dog
، اما در نیستند Animal
. یک بازیگر باریک (یا صریح) در جهت مخالف رخ می دهد:
Animal animalCat = new Cat();
Animal animalDog = new YorkshireTerrier();
Cat cat =(Cat)animalCat;
YorkshireTerrier dog = (YorkshireTerrier) animalDog;
ما به وضوح نشان دادهایم که میخواهیم این شی را به چه نوعی بفرستیم. اما، مراقب باشید!!! اگر این کار را به این صورت انجام دهید:
Animal animalCat = new Cat();
YorkshireTerrier dog = (YorkshireTerrier) animalCat;
کامپایلر از این کد عبور می کند. اما RunTime
آن را به شما پرتاب می کند:
Exception in thread "main" java.lang.ClassCastException: Animals.Cat cannot be cast to Animals.YorkshireTerrier
RunTime
می بیند که دو کلاس مختلف Cat
وجود دارد . YorkshireTerrier
برای جلوگیری از ClassCastException در طول تبدیل باریک، از instanceof
.
Animal animalCat = new Cat();
if (animalCat instanceof YorkshireTerrier)
{
YorkshireTerrier dog = (YorkshireTerrier) animalCat;
}
اگر animalCat
اینطور باشد YorkshireTerrier
، تخصیص اتفاق می افتد، اگر نه، هیچ اتفاقی نمی افتد.
حالا اگر روشها را گم کنیم و بتوانیم چنین خطاهایی را دریافت کنیم، چرا این کار ضروری است
بیایید به کدی که مطابق نمودار در شکل ساخته شده نگاه کنیم. 1 . کلاسAnimal
public abstract class Animal
{
String name;
int age;
String nameOfClass = getClass().getSimpleName();
public void eat(){
System.out.println(nameOfClass + ": Omnomnom");
}
public void sleep(){
System.out.println(nameOfClass + ": Z-z-z-z");
}
}
کلاسی WildAnimal
که از آن ارث می بردAnimal
public abstract class WildAnimal extends Animal
{
public void steelChicken()
{
System.out.println(nameOfClass+": Muhaha,I stole a chicken!");
}
}
کلاسی Pet
که از آن ارث می بردAnimal
public abstract class Pet extends Animal
{
public void peeInTray(){
System.out.println(nameOfClass + ": Master, I peed");
}
}
کلاسی Fox
که از آن ارث می بردWildAnimal
public class Fox extends WildAnimal
{
public void eatColobok(){
System.out.println(nameOfClass + ": I will eat you, Colobok");
}
}
کلاسی Wolf
که از آن ارث می بردWildAnimal
public class Wolf extends WildAnimal
{
public void hawlAtTheMoon(){
System.out.println(nameOfClass + ": Ouuuuu!!!Ouuuu!!!");
}
}
کلاسی Cat
که از آن ارث می بردPet
public class Cat extends Pet
{
public void sleepOnKeyboard(){
System.out.println(nameOfClass + ": Master, stop working!!I wanna sleep on your keyboard");
}
}
کلاسی YorkshireTerrier
که از آن ارث می بردPet
public class YorkshireTerrier extends Pet
{
public void bark(){
System.out.println(nameOfClass + ": Meow!!! Meow!!!");
}
}
وضعیت را تصور کنید. ما باید همه حیوانات را در یک لیست جمع آوری کنیم، به آنها غذا دهیم و سپس آنها را در رختخواب بگذاریم. این کار آسان است اگر ما ArrayList
حیوانات را ایجاد کنیم ( Animal
). و سپس روش های مربوط به هر حیوان را فراخوانی می کنیم:
public class ZOO
{
public static void main(String[] args)
{
List<Animal> allAnimals = new ArrayList<>();
allAnimals.add(new Cat());
allAnimals.add(new Wolf());
allAnimals.add(new Fox());
allAnimals.add(new YorkshireTerrier());
for (Animal animal : allAnimals)
{
animal.eat();
animal.sleep();
}
}
}
من نمی animal
توانم روش bark()
یا sleepOnKeyboard()
. از آنجا که ورق allAnimals
حاوی یک گربه، یک گرگ، یک یوریک و یک روباه است، اما آنها به Animal
. و آنها فقط روش هایی را دارند که در Animal
. این خیلی خوب است، زیرا اگر میتوانیم همه روشها را فراخوانی کنیم، پس چرا به گرگی نیاز داریم که روی صفحهکلید بخوابد، یا یوریکی که جوجهها را میدزدد؟ با تشکر از توجه شما. امیدوارم این مقاله برای شما مفید باشد. انتقاد و نظر پذیرفته میشود)
GO TO FULL VERSION