Selamat hari, lelaki Javarash. Saya mula menerima soalan tentang menghantar jenis rujukan dalam Java. Untuk tidak menceritakan perkara yang sama setiap kali, saya memutuskan untuk menulis artikel pendek.
Mula-mula, mari kita lihat jenis pemutus.
Pemutus jenis (penukaran jenis) ialah penukaran nilai pembolehubah satu jenis kepada nilai jenis lain. Mari kita lihat contoh apa itu dan dengan apa ia dimakan. Kami mempunyai beberapa hierarki kelas ( lihat Rajah 1 ). Di sini anda boleh melihat semua kelas hierarki, siapa yang mewarisi siapa, dan kaedah setiap kelas. Terdapat tambahan mengembang dan mengecut. Kami melihat bahawa kelas ituCat
adalah keturunan kelas Pet
. Pet
, seterusnya, adalah pengganti kelas Animal
. Apabila kita menulis:
Animal animalCat = new Cat();
Animal animalDog = new YorkshireTerrier();
Ini ialah pelakon yang sedang berkembang (atau yang tersirat). Kami telah mengembangkan pautan animalCat
dan animalDog
. Mereka merujuk kepada objek Cat
dan Dog
. Dengan lakonan sedemikian, kita tidak boleh animalCat/animalDog
memanggil kaedah melalui rujukan yang ada dalam Cat/Dog
, tetapi yang tidak ada dalam Animal
. Barisan penyempitan (atau eksplisit) berlaku dalam arah yang bertentangan:
Animal animalCat = new Cat();
Animal animalDog = new YorkshireTerrier();
Cat cat =(Cat)animalCat;
YorkshireTerrier dog = (YorkshireTerrier) animalDog;
Kami telah menyatakan dengan jelas jenis yang ingin kami hantar objek ini. TETAPI SILA BERHATI-HATI!!! Jika anda melakukannya seperti ini:
Animal animalCat = new Cat();
YorkshireTerrier dog = (YorkshireTerrier) animalCat;
pengkompil akan melangkau kod ini. Tetapi RunTime
ia akan membuang kepada anda:
Exception in thread "main" java.lang.ClassCastException: Animals.Cat cannot be cast to Animals.YorkshireTerrier
RunTime
melihat bahawa Cat
terdapat YorkshireTerrier
dua kelas yang berbeza. Untuk mengelakkan ClassCastException semasa menyempitkan penukaran, gunakan instanceof
.
Animal animalCat = new Cat();
if (animalCat instanceof YorkshireTerrier)
{
YorkshireTerrier dog = (YorkshireTerrier) animalCat;
}
Jika animalCat
ya YorkshireTerrier
, maka tugasan akan berlaku, jika tidak, tiada apa yang akan berlaku.
Sekarang mengapa ini perlu jika kita kehilangan kaedah dan boleh mendapat ralat sedemikian
Mari lihat kod yang saya buat mengikut rajah dalam Rajah. 1 . KelasAnimal
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");
}
}
Kelas WildAnimal
yang mewarisi daripadaAnimal
public abstract class WildAnimal extends Animal
{
public void steelChicken()
{
System.out.println(nameOfClass+": Muhaha,I stole a chicken!");
}
}
Kelas Pet
yang mewarisi daripadaAnimal
public abstract class Pet extends Animal
{
public void peeInTray(){
System.out.println(nameOfClass + ": Master, I peed");
}
}
Kelas Fox
yang mewarisi daripadaWildAnimal
public class Fox extends WildAnimal
{
public void eatColobok(){
System.out.println(nameOfClass + ": I will eat you, Colobok");
}
}
Kelas Wolf
yang mewarisi daripadaWildAnimal
public class Wolf extends WildAnimal
{
public void hawlAtTheMoon(){
System.out.println(nameOfClass + ": Ouuuuu!!!Ouuuu!!!");
}
}
Kelas Cat
yang mewarisi daripadaPet
public class Cat extends Pet
{
public void sleepOnKeyboard(){
System.out.println(nameOfClass + ": Master, stop working!!I wanna sleep on your keyboard");
}
}
Kelas YorkshireTerrier
yang mewarisi daripadaPet
public class YorkshireTerrier extends Pet
{
public void bark(){
System.out.println(nameOfClass + ": Meow!!! Meow!!!");
}
}
Bayangkan keadaannya. Kita perlu mengumpulkan semua haiwan dalam satu senarai, memberi mereka makan dan kemudian meletakkan mereka di atas katil. Ini mudah dilakukan jika kita mencipta ArrayList
haiwan ( Animal
). Dan kemudian kami memanggil kaedah yang sepadan untuk setiap haiwan:
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();
}
}
}
Saya tidak boleh animal
memanggil kaedah bark()
atau sleepOnKeyboard()
. Kerana helaian itu allAnimals
mengandungi kucing, serigala, yorick dan musang, tetapi ia dikurangkan kepada Animal
. Dan mereka hanya mempunyai kaedah yang ada dalam Animal
. Ini sangat bagus, kerana jika kita boleh memanggil semua kaedah, maka mengapa kita memerlukan serigala yang tidur di atas papan kekunci, atau yorick yang mencuri ayam? Terima kasih kerana memberi perhatian. Saya harap artikel ini berguna kepada anda. Kritikan dan komen dialu-alukan)
GO TO FULL VERSION