1. Typecasting

Pembolehubah yang menyimpan jenis rujukan (kelas) juga boleh ditukar kepada jenis yang berbeza. Tetapi ini hanya berfungsi dalam hierarki jenis tunggal. Mari kita lihat contoh mudah. Katakan kita mempunyai hierarki kelas berikut, di mana kelas di bawah mewarisi kelas di atas.

Typecasting

Typecasting jenis rujukan dan juga yang primitif juga dikategorikan sebagai sama ada melebar dan menyempit.

Kami melihat bahawa kelas Kucing mewarisi kelas Haiwan, dan kelas Haiwan, seterusnya, mewarisi kelas Haiwan.

Jika kita menulis kod seperti ini:

Animal kitten = new Cat();

Ini ialah penukaran jenis yang semakin meluas . Ia juga dipanggil lakonan tersirat. Kami telah meluaskan rujukan kucing supaya ia kini merujuk kepada objek Kucing . Dengan penukaran jenis seperti ini, kami tidak akan dapat menggunakan rujukan anak kucing untuk memanggil kaedah yang terdapat dalam kelas Cat tetapi tiada dalam kelas Haiwan .

Penukaran yang mengecil (atau pelakon eksplisit) berlaku dalam arah yang bertentangan:

Cat cat = (Cat) kitten;

Kami secara eksplisit menyatakan bahawa kami ingin menghantar rujukan yang disimpan dalam pembolehubah anak kucing (yang jenisnya ialah Haiwan ) kepada jenis Kucing .



2. Menyemak jenis objek

Tetapi anda perlu berhati-hati di sini. Jika anda melakukan ini:

Animal beast = new Cat();
Wolf grayWolf = (Wolf) beast;

Pengkompil akan membenarkan kod ini, tetapi akan terdapat ralat apabila program dijalankan! JVM akan membuang pengecualian:

Exception in thread "main" java.lang.ClassCastException: Cat cannot be cast to a Wolf

Rujukan kepada objek Cat hanya boleh disimpan dalam pembolehubah yang jenisnya ialah nenek moyang kelas Kucing: Haiwan Kesayangan, Haiwan atau Objek.

Kenapa begitu?

Perkara yang berkaitan di sini ialah rujukan objek digunakan untuk merujuk kepada kaedah dan pembolehubah objek tersebut . Dan tidak akan ada sebarang masalah jika kita menggunakan pembolehubah Haiwan untuk menyimpan rujukan kepada objek Kucing: jenis Kucing sentiasa mempunyai pembolehubah dan kaedah jenis Haiwan — ia mewarisinya!

Tetapi jika JVM membenarkan kami menyimpan rujukan kepada objek Cat dalam pembolehubah Wolf, maka kami mungkin mempunyai situasi di mana kami mungkin cuba menggunakan pembolehubah greyWolf untuk memanggil kaedah yang tidak wujud dalam objek Cat yang disimpan dalam pembolehubah itu . Sebab itu susunan ini tidak dibenarkan.

Java mempunyai operator khas instanceofyang membolehkan anda menyemak sama ada objek adalah jenis tertentu dan oleh itu boleh disimpan ke dalam pembolehubah jenis tertentu. Ia kelihatan agak mudah:

variable instanceof Type

Contoh:

Animal beast = new Cat();
if (beast instanceof Wolf)
{
   Wolf grayWolf = (Wolf) beast;
}

Kod ini tidak akan menyebabkan ralat — walaupun pada masa jalan.

Berikut adalah beberapa lagi contoh yang menggambarkan keadaan:

Memperluaskan penukaran jenis Penerangan
Cow cow = new Whale();

Ini ialah penukaran pelebaran klasik — tiada operator penukaran jenis diperlukan. Kini hanya kaedah yang ditakrifkan dalam Cowkelas boleh dipanggil pada Whaleobjek.

Pada cowpembolehubah , pengkompil hanya akan membenarkan anda memanggil kaedah yang Cowada pada jenisnya (kelas).

Menyempitkan penukaran jenis
Cow cow = new Whale();
if (cow instanceof Whale)
{
   Whale whale = (Whale) cow;
}
Penukaran penyempitan klasik: Anda perlu menambah semakan jenis dan operator cast.
Pembolehubah Cow cowmenyimpan rujukan kepada Whaleobjek.
Kami mengesahkan bahawa ini adalah kesnya , dan kemudian melakukan penukaran jenis (menyempitkan). Atau ia juga dipanggil:
pelakon jenis
.

Cow cow = new Cow();
Whale whale = (Whale) cow; // Exception
Anda boleh menyempitkan jenis rujukan tanpa menyemak jenis objek.
Jika cowpembolehubah merujuk kepada objek yang bukan Whale, maka InvalidClassCastExceptionakan dijana.


3. Memanggil kaedah asal: superkata kunci

Apabila mengatasi kaedah kelas induk, kadangkala daripada menggantikannya dengan kaedah kami sendiri, kami hanya mahu menambahnya sedikit.

Alangkah baiknya jika kita boleh menggunakan kaedah kelas induk dalam kaedah kita, dan kemudian melaksanakan beberapa kod kita sendiri. Atau mungkin mula-mula laksanakan kod kita sendiri, dan kemudian panggil kaedah kelas induk.

Dan Java membolehkan kita melakukannya. Untuk memanggil kaedah kelas induk, lakukan ini:

super.method(arguments);

Contoh:

class PeaceTime
{
   public double getPi()
   {
      return 3.14;
   }
}

class WarTime extends PeaceTime
{
   public double getPi()
   {
      return super.getPi()*2;  // 3.14*2
   }
}

Pada masa perang, nilai Piboleh lebih daripada 6! Sudah tentu, kami bergurau, tetapi contoh ini menunjukkan bagaimana ini semua boleh berfungsi.

Berikut ialah beberapa lagi contoh untuk menjelaskan sedikit perkara:

Kod Penerangan
class Cow
{
   public void printAll()
   {
      printColor();
      printName();
   }

   public void printColor()
   {
      System.out.println("I'm a white whale");
   }

   public void printName()
   {
      System.out.println("I'm a cow");
   }
}

class Whale extends Cow
{
   public void printName()
   {
      System.out.print("This is incorrect: ");
      super.printName();
      System.out.println("I'm a whale");
   }
}
Cowdan Whalekelas
public static void main(String[] args)
{
   Whale whale = new Whale();
   whale.printAll();
}
Output skrin akan menjadi:
I'm a white whale
This is incorrect: I'm a cow
I'm a whale

Ini adalah perkara yang sukar. Secara jujur, ia adalah salah satu perkara yang paling sukar dalam OOP . Yang berkata, anda perlu mengetahui dan memahaminya.