JavaRush /Blog Jawa /Random-JV /Ekspansi lan kontraksi jinis referensi

Ekspansi lan kontraksi jinis referensi

Diterbitake ing grup
Hello! Ing salah siji saka ceramah sadurunge, kita rembugan casting jinis primitif. Ayo kita ngelingi sedhela apa sing kita omongake. Ekspansi lan kontraksi jinis referensi - 1Kita makili jinis primitif (ing kasus iki, numerik) minangka boneka nesting miturut jumlah memori sing dikuwasani. Nalika sampeyan ngelingi, nempatake boneka nesting sing luwih cilik dadi sing luwih gedhe bakal gampang ing urip nyata lan ing program Java.
public class Main {
   public static void main(String[] args) {
        short smallNumber = 100;
        int bigNumber =  smallNumber;
        System.out.println(bigNumber);
   }
}
Iki minangka conto konversi otomatis, utawa ekstensi . Iki kedadeyan dhewe, mula ora perlu nulis kode tambahan. Pungkasane, kita ora nindakake apa-apa sing ora biasa: kita mung nyelehake boneka nesting sing luwih cilik dadi boneka nesting sing luwih gedhe. Iku prakara liyane yen kita nyoba kanggo nindakake ngelawan lan sijine boneka matryoshka gedhe menyang cilik. Iki ora bisa ditindakake ing urip, nanging ing program bisa ditindakake. Nanging ana siji caveat. Yen kita nyoba nglebokake nilai intmenyang variabel short, ora bakal gampang. Sawise kabeh, mung 16 bit informasi bisa pas menyang variabel short, nanging nilai intnjupuk 32 bit! Akibaté, nilai sing dikirim bakal kleru. Compiler bakal menehi kita kesalahan (" wong lanang, sampeyan lagi nindakake soko curiga! "), nanging yen kita tegas nemtokake jinis apa kita casting Nilai kita, iku isih bakal nindakake operasi kuwi.
public class Main {

   public static void main(String[] args) {

       int bigNumber = 10000000;

       bigNumber = (short) bigNumber;

       System.out.println(bigNumber);

   }

}
Ing conto ing ndhuwur, kita mung nindakake. Operasi rampung, nanging amarga shortmung 16 saka 32 bit sing cocog karo variabel kasebut, nilai final distorsi, lan minangka asil kita nampa nomer -27008 . Operasi iki diarani konversi eksplisit, utawa narrowing .

Conto ekstensi lan kontraksi jinis referensi

Saiki kita bakal ngomong babagan operasi sing padha, nanging ora ditrapake kanggo jinis primitif, nanging kanggo obyek lan variabel referensi ! Kepiye carane iki bisa digunakake ing Jawa? Cukup prasaja bener. Ana obyek sing ora ana hubungane. Iku bakal logis kanggo nganggep sing padha ora bisa diowahi kanggo saben liyane kanthi eksplisit utawa otomatis:
public class Cat {
}

public class Dog {
}

public class Main {

   public static void main(String[] args) {

       Cat cat = new Dog();//error!

   }

}
Ing kene kita bakal, mesthi, entuk kesalahan. Kelas kasebut ora Catana Doghubungane, lan kita durung nulis "konverter" saka siji menyang liyane. Iku logis yen kita ora bakal bisa nindakake iki: compiler ora ngerti carane ngowahi obyek kasebut ing antarane saben liyane. Iku prakara liyane yen obyek disambungake kanggo saben liyane! kepriye? Kaping pisanan, nggunakake warisan. Ayo nyoba nggawe sistem kelas cilik kanthi warisan. Kita bakal duwe kelas umum sing makili kewan:
public class Animal {

   public void introduce() {

       System.out.println("i'm Animal");
   }
}
Kéwan, sing sampeyan ngerti, iku domestik lan alam bébas:
public class WildAnimal extends Animal {

   public void introduce() {

       System.out.println("i'm WildAnimal");
   }
}

public class Pet extends Animal {

   public void introduce() {

       System.out.println("i'm Pet");
   }
}
Contone, ayo njupuk asu - asu domestik lan coyote:
public class Dog extends Pet {

   public void introduce() {

       System.out.println("i'm Dog");
   }
}





public class Coyote extends WildAnimal {

   public void introduce() {

       System.out.println("i'm Coyote");
   }
}
Kelas kita sengaja paling primitif supaya luwih gampang dingerteni. Kita ora butuh lapangan ing kene, lan siji cara cukup. Ayo nyoba mbukak kode ing ngisor iki:
public class Main {

   public static void main(String[] args) {

       Animal animal = new Pet();
       animal.introduce();
   }
}
Apa sampeyan mikir bakal output kanggo console? Apa metode introducekelas Petutawa kelas bisa digunakake Animal? Coba benerake jawaban sampeyan sadurunge nerusake maca. Lan iki asile! i'm Pet Kenapa jawabane dadi kaya ngono? Iku prasaja. Kita duwe variabel induk lan obyek anak. Kanthi nulis:
Animal animal = new Pet();
Kita wis nggedhekake jinis referensiPet lan nyimpen obyek kasebut ing variabel Animal. Kaya jinis primitif, ekstensi saka jinis referensi ing Jawa ditindakake kanthi otomatis. Ora perlu nulis kode tambahan kanggo iki. Saiki kita duwe obyek anak ditempelake referensi tiyang sepah, lan minangka asil kita weruh sing cara disebut ing kelas anak. Yen sampeyan isih durung ngerti sebabe kode iki bisa digunakake, tulis maneh nganggo basa sing gampang:
Животное животное = new ДомашнееЖивотное();
Ora ana masalah, ta? Mbayangno iki urip nyata, lan link ing kasus iki minangka tag kertas prasaja sing ngandika "Animal." Yen sampeyan njupuk potongan kertas kasebut lan dipasang ing iker-iker rasukan pet, kabeh bakal apik. Kewan apa wae isih kewan! Proses mbalikke, yaiku, mindhah wit pusaka menyang ahli waris, minangka penyempitan:
public class Main {

   public static void main(String[] args) {

       WildAnimal wildAnimal = new Coyote();

       Coyote coyote = (Coyote) wildAnimal;

       coyote.introduce();
   }
}
Kaya sing sampeyan ngerteni, ing kene kita kanthi jelas nuduhake kelas endi sing arep kita lakoni. Sadurunge kita duwe variabel WildAnimal, lan saiki Coyote, sing mudhun ing wit warisan. Logis yen kompiler ora bakal ngliwati operasi kasebut tanpa indikasi sing jelas, nanging yen sampeyan nemtokake jinis ing kurung, kabeh bakal bisa digunakake. Ekspansi lan kontraksi jinis referensi - 2 Ayo goleki conto liyane, sing luwih menarik:
public class Main {

   public static void main(String[] args) {

       Pet pet = new Animal();//error!
   }
}
Compiler mbuwang kesalahan! Apa sebabe? Kasunyatane yaiku sampeyan nyoba nemtokake obyek induk menyang variabel anak. Ing tembung liyane, sampeyan pengin nindakake iki:
ДомашнееЖивотное домашнееЖивотное = new Животное();
Nanging bisa uga yen kita kanthi tegas nuduhake jinis sing arep kita lakoni, kita bakal sukses? Angka katon bisa, ayo nyoba! :)
public class Main {

   public static void main(String[] args) {

       Pet pet = (Pet) new Animal();
   }
}
Pangecualian ing thread "utama" java.lang.ClassCastException: Animal ora bisa matak kanggo Pet Error! Compiler ora sambat wektu iki, nanging minangka asil kita nampa pangecualian. Kita wis ngerti alasane: kita nyoba nemtokake obyek induk menyang variabel anak. Yagene, nyatane, iki ora bisa ditindakake? Amarga ora kabeh Kewan iku Pet. Sampeyan nggawe obyek Animallan nyoba kanggo nemtokake menyang variabel Pet. Nanging, contone, coyote uga Animal, nanging ora Pet, kewan domestik. Ing tembung liyane, nalika sampeyan nulis:
Pet pet = (Pet) new Animal();
new Animal()Kewan apa wae bisa ana , lan ora kudu domestik! Alamiah, variabel sampeyan Pet petmung cocok kanggo nyimpen pets (lan turunane), lan ora kanggo kabeh wong. Mulane, kanggo kasus kaya mengkono, pangecualian khusus digawe ing Jawa - ClassCastExceptionkesalahan nalika casting kelas. Ayo ngomong maneh supaya luwih cetha. Variabel induk (referensi) bisa nuding obyek saka kelas turunan:
public class Main {

   public static void main(String[] args) {

       Pet pet =  new Pet();
       Animal animal = pet;

       Pet pet2 = (Pet) animal;
       pet2.introduce();
   }
}
Contone, kita ora bakal duwe masalah ing kene. Kita duwe obyek Petsing ditunjuk kanthi tautan Pet. Banjur pranala anyar wiwit ngarah menyang obyek sing padha Animal. Sawise kita nindakake konversi animalmenyang Pet. Yagene kita nindakake iki, kanthi cara? Pungkasan kita entuk pangecualian! Amarga wektu iki obyek asli kita Pet pet!
Pet pet =  new Pet();
Lan ing conto sadurunge iku obyek Animal:
Pet pet = (Pet) new Animal();
Variabel turunan ora bisa diwenehi obyek leluhur. Kosok baline, sampeyan bisa nindakake.
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION