Lompat ke konten Lompat ke sidebar Lompat ke footer

Pengertian Dan Pola Jadwal Dari Inheritance & Polymorphism

pengertian dan pola kegiatan dari Inheritance & Polymorphism

Introduction

Pemrograman berorientasi objek memungkinkan Anda memperoleh kelas gres dari kelas yang ada. Ini ialah disebut warisan Warisan ialah fitur penting dan berpengaruh di Java untuk memakai kembali perangkat lunak. Misalkan Anda mendefinisikan kelas pada bulat model, persegi panjang, dan segitiga. Ini kelas mempunyai banyak fitur umum. Apa cara terbaik untuk mendesain kelas-kelas ini supaya terhindar redundansi dan membuat sistem gampang dipahami dan gampang perawatannya? Jawabannya ialah gunakan pewarisan.

Superclasses and Subclasses

Anda memakai kelas untuk memodelkan objek dengan tipe yang sama. Kelas yang berbeda mungkin mempunyai kesamaan sifat dan perilaku, yang bisa digeneralisasi di kelas yang bisa dibagi oleh orang lainkelas. Warisan memungkinkan Anda mendefinisikan kelas umum dan kemudian memperluasnya menjadi lebih terspesialisasi kelas. Kelas khusus mewarisi sifat dan metode dari kelas umum. Pertimbangkan benda geometris. Misalkan Anda ingin merancang kelas untuk model geometris benda menyerupai bulat dan persegi panjang. Benda geometris mempunyai banyak sifat umum dan perilaku. Mereka bisa digambar dengan warna tertentu, terisi atau terisi. Makara kelas umum

 Gambar 1

GeometricObject sanggup dipakai untuk memodelkan semua objek geometris. Kelas ini berisi properti warna dan isi dan sesuai mereka dapatkan dan menetapkan metode. Asumsikan bahwa kelas ini juga berisi properti tanggalCreated dan metode getDateCreated () dan toString (). Metode toString () mengembalikan representasi string untuk objek. Karena bulat itu istimewa Jenis objek geometris, ia membuatkan sifat dan metode yang sama dengan benda geometris lainnya. Jadi, masuk nalar untuk memilih kelas Lingkaran yang memperluas kelas GeometrikObject. Juga, Rectangle juga sanggup dinyatakan sebagai subclass dari GeometricObject. Gambar 1 memperlihatkan kekerabatan antara kelas-kelas ini. Panah yang menunjuk ke superclass dipakai untuk memperlihatkan kekerabatan warisan antara dua kelas yang terlibat.

Dalam terminologi Java, kelas C1 yang diperluas dari kelas C2 lain disebut subclass, dan C2 disebut superclass. Superclass juga disebut sebagai kelas induk, atau kelas dasar, dan a subclass sebagai kelas anak, kelas diperpanjang, atau kelas turunan. Sebuah subkelas mewarisi sanggup diakses bidang data dan metode dari superclass-nya dan mungkin juga menambahkan field dan metode data baru. Kelas Lingkaran mewarisi semua bidang data dan metode yang sanggup diakses dari Geometric-Kelas objek Selain itu, ia mempunyai field data baru, radius, dan yang terkait get dan setmetode. Ini juga berisi metode getArea (), getPerimeter (), dan getDiameter () untuk mengembalikan area, keliling, dan diameter lingkaran. Kelas Rectangle mewarisi semua bidang dan metode data yang gampang diakses dari Kelas GeometrikObject Selain itu, ia mempunyai lebar dan tinggi bidang data dan yang terkait mendapatkan dan memutuskan metode. Ini juga berisi metode getArea () dan getPerimeter () untuk mengembalikan area dan keliling persegi panjang.


LISTING 1 GeometricObject1.java 

1 public class GeometricObject1 {
2 private String color = "white";
3 private boolean filled;
4 private java.util.Date dateCreated;
5
6 /** Construct a default geometric object */
7 public GeometricObject1() {
8
9 }
10
11 /** Construct a geometric object with the specified color
12 * and filled value */
13 public GeometricObject1(String Color, boolean filled) {
14
15 this.color = color;
16 this.filled = filled;
17 }
18
19 /** Return color */
20 public String getColor() {
21 return color;
22 }
23
24 /** Set a new color */
25 public void setColor(String color) {
26 this.color = color;
27 }
28
29 /** Return filled. Since filled is boolean,
30 its get method is named isFilled */
31 public boolean isFilled() {
32 return filled;
33 }
34
35 /** Set a new filled */
36 public void setFilled(boolean filled) {
37 this.filled = filled;
38 }
39
40 /** Get dateCreated */
41 public java.util.Date getDateCreated() {
42 return dateCreated;
43 }
44
45 /** Return a string representation of this object */
46 public String toString() {
47 return "created on " + dateCreated + "\ncolor: " + color +
48 " and filled: " + filled;
49 }
50 }


LISTING 2 Circle4.java 

 public class Circle4 {
2 private double radius;
3
4 public Circle4() {
5 }
6
7 public Circle4(double radius) {
8 this.radius = radius;
9 }
10
11 public Circle4(double radius, String color, boolean filled) {
12 this.radius = radius;
13 setColor(color);
14 setFilled(filled);
15 }
16
17 /** Return radius */
18 public double getRadius() {
19 return radius;
20 }
21
22 /** Set a new radius */
23 public void setRadius(double radius) {
24 this.radius = radius;
25 }
26
27 /** Return area */
28 public double getArea() {
29 return radius * radius * Math.PI;
30 }
31
32 /** Return diameter */
33 public double getDiameter() {
34 return 2 * radius;
35 }
36
37 /** Return perimeter */
38 public double getPerimeter() {
39 return 2 * radius * Math.PI;
40 }
41
42 /* Print the circle info */
43 public void printCircle() {
44 System.out.println("The circle is created "+ +
45 " and the radius is " + radius);
46 }
47 }

  Kelas Lingkaran memperluas kelas GeometricObject (Listing 2) dengan memakai sintak berikut :
Gambar 2
Kata kunci meluas (baris 1) memberitahu kompiler bahwa kelas Lingkaran memanjang GeometricObject kelas, sehingga mewarisi metode getColor,setColor, isFilled, setFilled, dan toString.

Lingkaran konstruktor yang kelebihan beban (radius ganda, warna string, boolean diisi) dilaksanakan dengan menerapkan metode setColor dan setFilled untuk mengatur warna dan sifat terisi (baris 11-15). Kedua metode umum ini didefinisikan dalam kelas dasar GeometricObject dan diwarisi di
Circle. Jadi, mereka bisa dipakai di kelas turunan. Anda mungkin mencoba untuk memakai warna bidang data dan pribadi mengisi konstruktor sebagai berikut:

public Circle4(double radius, String color, boolean filled) {
this.radius = radius;
this.color = color; // Illegal
this.filled = filled; // Illegal
}

Ini salah, alasannya ialah bidang data pribadi berwarna dan terisi pada Geometric-Kelas objek tidak sanggup diakses di kelas manapun selain di kelas GeometricObject diri. Satu-satunya cara untuk membaca dan memodifikasi warna dan isi ialah melalui cara mendapatkan dan mengaturnya metode. 

Kelas Rectangle (Listing 3) memperluas kelas GeometricObject (Listing 2) memakai sintaks berikut:
Gambar 3
Kata kunci meluas (baris 1) memberitahu kompiler bahwa kelas Rectangle memanjang GeometricObject kelas, sehingga mewarisi metode getColor, setColor, isFilled, setFilled, dan toString. 

LISTING 3 Rectangle1.java

1 public class Rectangle1 extends GeometricObject1 {
2 private double width;
3 private double height;
4
5 public Rectangle1() {
6 }
7
8 public Rectangle1(double width, double height) {
9 this.width = width;
10 this.height = height;
11 }
12
13 public Rectangle1(double width, double height, String color,
14 boolean filled) {
15 this.width = width;
16 this.height = height;
17 setColor(color);
18 setFilled(filled);
19 }
20
21 /** Return width */
22 public double getWidth() {
23 return width;
24 }
25
26 /** Set a new width */
27 public void setWidth(double width) {
28 this.width = width;
29 }
30
31 /** Return height */
32 public double getHeight() {
33 return height;
34 }
35
36 /** Set a new height */
37 public void setHeight(double height) {
38 this.height = height;
39 }
40
41 /** Return area */
42 public double getArea() {
43 return width * height;
44 }
45
46 /** Return perimeter */
47 public double getPerimeter() {
48 return 2 * (width + height);
49 }
50 }

Kode pada Listing 11.4 membuat objek Circle and Rectangle dan memanggil metode pada objek ini. Metode toString () diwarisi dari kelas GeometricObject dan dipanggil dari objek Circle (baris 4) dan objek Rectangle (baris 10).

LISTING 4 TestCircleRectangle.java

1 public class TestCircleRectangle {
2 public static void main(String[] args) {
3 Circle4 circle = new Circle4(1);
4 System.out.println("A circle "+ circle.toString() );
5 System.out.println("The radius is "+ circle.getRadius() );
6 System.out.println("The area is "+ circle.getArea() );
7 System.out.println("The diameter is "+ circle.getDiameter() );
8
9 Rectangle1 rectangle = new Rectangle1(2, 4);
10 System.out.println("\nA rectangle "+ rectangle.toString()
);
11 System.out.println("The area is "+ rectangle.getArea());
12 System.out.println("The perimeter is " +
13 rectangle.getPerimeter() );
14 }
15 }

Lingkaran dibentuk pada Jum 24 Sep 20:31:02 EDT 2009
warna: putih dan penuh: salah
Jari-jarinya ialah 1.0
Daerahnya ialah 3.141592653589793
Diameternya 2.0
Sebuah persegi panjang dibentuk pada Kamis 24 Sep 20:31:02 EDT 2009
warna: putih dan penuh: salah
Wilayahnya 8,0
Perimeter ialah 12.0

Hal-hal berikut wacana warisan perlu dicatat:
• Berlawanan dengan interpretasi konvensional, subkelas bukanlah
subset dari superclass-nya. Sebenarnya, sebuah subkelas biasanya
berisi lebih banyak informasi dan metode daripada itu superclass.
• Bidang data pribadi dalam superclass tidak sanggup diakses di luar
kelas. Oleh alasannya ialah itu, mereka tidak bisa dipakai pribadi di
subclass. Namun, mereka sanggup diakses / dimutasi melalui accessor
/ mutator publik jikalau didefinisikan dalam superclass. Tidak semuahubungan
harus dimodelkan memakai pewarisan. Misalnya, a
persegi ialah persegi panjang, tapi sebaiknya Anda tidak
memilih kelas Square untuk memperpanjang a. Rectangle class,
alasannya ialah tidak ada yang memperpanjang (atau melengkapi) dari segi
empat ke kotak. Sebaliknya Anda harus mendefinisikan kelas
Square untuk memperpanjang Kelas GeometrikObject Untuk kelas
A untuk memperpanjang kelas B, A harus berisi lebih banyak
informasi rinci dari B.
• Warisan dipakai untuk memodelkan is-a relationship. Jangan
membabi buta memperpanjang kelas saja demi penggunaan kembali
metode. Misalnya, tidak masuk nalar untuk kelas Pohon
memperpanjang kelas Person, meskipun mereka mempunyai sifat
umum menyerupai tinggi tubuh dan berat. Sebuah subclass dan
superclass-nya niscaya mempunyai hubungan-adalah.
• Beberapa bahasa pemrograman memungkinkan Anda mendapatkan
subkelas dari beberapa kelas. Kemampuan ini dikenal dengan
multiple inheritance. Java, bagaimanapun, tidak mengizinkan
banyak warisan. Kelas Java sanggup mewarisi pribadi dari hanya satu
superclass. Ini Pembatasan dikenal sebagai single inheritance. Jika
Anda memakai kata kunci yang diperluas untuk didefinisikan
sebuah subclass, hanya mengizinkan satu kelas induk. Meski
demikian, multiple inheritance bisa jadi dicapai melalui antarmuka,
yang akan diperkenalkan di § 14,4, "Antarmuka."

Using the super Keyword

Subclass mewarisi bidang data dan metode yang sanggup diakses dari
superclass-nya. Apakah itu mewarisi konstruktor? Dapatkah superclass
konstruktor dipanggil dari subclass? Bagian ini membahas pertanyaan ini
dan ramifikasinya.
§10.4, "Referensi ini," memperkenalkan penggunaan kata kunci ini
untuk acuan memanggil objek Kata kunci super mengacu pada superclass
kelas di mana super muncul Ini bisa dipakai dengan dua cara:
• Untuk memanggil konstruktor superkelas.
• Untuk memanggil metode superclass

Calling Superclass Constructors

 Sintaks untuk memanggil konstruktor superclass adalah:

super(), atau super (parameter);

Pernyataan super () memanggil konstruktor no-arg dari superclass-nya, dan pernyataannya super (argumen) memanggil konstruktor superclass yang sesuai dengan argumennya. Itu pernyataan super () atau super (argumen) harus muncul di baris pertama konstruktor subkelas; ini ialah satu-satunya cara untuk secara eksplisit memanggil konstruktor superkelas. Misalnya, konstruktor pada baris 11-15 pada Listing 11.2 sanggup diganti dengan instruksi berikut:

public Circle4 (radius ganda, warna String, boolean diisi) {
super (warna, penuh);
this.radius = radius;
}

Constructor Chaining

Konstruktor sanggup memanggil konstruktor yang kelebihan muatan atau konstruktor superkelasnya. Jika tidak ada dipanggil secara eksplisit, compiler secara otomatis menempatkan super () sebagai pernyataan pertama di constructor. Sebagai contoh,
Gambar 4

Bagaimanapun, membangun sebuah instance dari kelas memanggil konstruktor dari semua superclasses sepanjang rantai pewarisan. Saat membangun objek subkelas, konstruktor subkelas pertama memanggil konstruktor superkelasnya sebelum melaksanakan tugasnya sendiri. Jika superclass ialah berasal dari kelas lain, konstruktor superclass memanggil konstruktor kelas induknya sebelum melaksanakan tugasnya sendiri. Proses ini berlanjut hingga konstruktor terakhir sepanjang hirarki pewarisan disebut ini ialah penjilidan konstruktor. 

Pertimbangkan instruksi berikut ini:

1 public class { Faculty extends Employee
2 public static void main(String[] args) {
3 new Faculty();
4 }
5
6 public Faculty(){
7 System.out.println("(4) Performs Faculty's tasks");
8 }
9 }
10
11 class Employee extends Person{
12 public Employee(){
13 this("(2) Invoke Employee's overloaded constructor");
14 System.out.println("(3) Performs Employee's tasks ");
15 }
16
17 public Employee(String s){
18 System.out.println(s);
19 }
20 }
21
22 class Person {
23 public Person(){
24 System.out.println("(1) Performs Person's tasks");
25 }
26 }

(1) Melakukan kiprah Orang
(2) Buat konstruktor karyawan yang kelebihan beban
(3) Melakukan kiprah Pegawai
(4) Melakukan kiprah Fakultas

Program ini menghasilkan output sebelumnya. Mengapa? Mari kita bahas alasannya. Sejalan 3, gres Fakultas () memanggil konstruktor no-arg dari Fakultas. Karena fakultas ialah subkelas dari Karyawan, konstruktor noarg karyawan dipanggil sebelum ada pernyataan di Fakultas konstruktor dijalankan Konstruktor tanpa-lawan karyawan memanggil konstruktor kedua Karyawan (baris 12). Karena Employee ialah subclass dari Person, Person's no-arg constructor dipanggil sebelum ada pernyataan dalam konstruktor kedua Karyawan dieksekusi. Proses ini digambarkan pada gambar di bawah ini:
Gambar 5
• Peringatan 
Jika sebuah kelas dirancang untuk diperluas, lebih baik memperlihatkan konstruktor tanpa argumen untuk menghindari pemrograman kesalahan Pertimbangkan instruksi berikut ini:

1 public class Apple extends Fruit {
2 }
3
4 class Fruit {
5 public Fruit(String name) {
6 System.out.println("Fruit's constructor is invoked");
7 }
8 }

Karena tidak ada konstruktor yang didefinisikan secara eksplisit di Apple, konstruktor default no-arg Apple didefinisikan secara implisit. Karena Apple ialah subclass Fruit, konstruktor default Apple secara otomatis memanggil konstruktor no-arg Fruit. Namun, Buah tidak mempunyai konstruktor no-arg, alasannya ialah Buah mempunyai konstruktor eksplisit yang didefinisikan. Karena itu, kegiatan tidak bisa dikompilasi. Panduan Desain Lebih baik memberi konstruktor no-arg (jika diinginkan) untuk setiap kelas supaya kelas gampang memperpanjang dan untuk menghindari kesalahan.

Memanggil Metode Superclass

Kata kunci super juga bisa dipakai untuk acuan metode selain konstruktor di superclass Sintaksnya menyerupai ini:

super.method (parameter);

Anda bisa menulis ulang metode printCircle () di kelas Circle sebagai berikut:

public void printCircle() {
System.out.println("The circle is created " +
super.getDateCreated() + " and the radius is " + radius);
}

Hal ini tidak perlu menempatkan super sebelum getDateCreated () dalam kasus ini, namun, alasannya ialah getDateCreated ialah metode di kelas GeometricObject dan diwarisi oleh Lingkari kelas. Namun demikian, dalam beberapa kasus, menyerupai yang ditunjukkan pada cuilan berikutnya, kata kunci super sangat dibutuhkan

Overriding Methods

Subclass mewarisi metode dari superclass. Terkadang diharapkan subkelas untuk memodifikasi penerapan metode yang didefinisikan dalam superclass. Ini disebut sebagai metode override Metode toString di kelas GeometricObject mengembalikan representasi string untuk objek geometris. Metode ini sanggup diganti untuk mengembalikan representasi string untuk a lingkaran. Untuk mengesampingkannya, tambahkan metode 
gres berikut pada Listing 2, Circle4.java: 

1 public class Circle4 extends GeometricObject1 {
2 // Other methods are omitted
3
4 /** Override the toString method defined in GeometricObject */
5 public String toString() {
6 return super.toString() + "\nradius is " + radius;}
7 }

Metode toString () didefinisikan dalam kelas GeometricObject dan dimodifikasi di Circle kelas. Kedua metode tersebut bisa dipakai di kelas Circle. Memanggil metode toString yang didefinisikan di kelas GeometricObject dari kelas Circle, gunakan super.toString () (baris 6).
Dapatkah subclass Circle mengakses metode toString yang didefinisikan di GeometricObject kelas memakai sintaks menyerupai super.super.toString ()? Tidak. Ini ialah kesalahan sintaksis.
Beberapa poin patut diperhatikan:
• Metode pola sanggup diganti hanya jikalau sanggup diakses. Makara metode pribadi tidak bisa ditimpa, alasannya ialah tidak bisa diakses di luar kelasnya sendiri. Jika sebuah metode didefinisikan dalam subclass bersifat privat di superclass-nya, kedua metode tersebut sepenuhnya tidak terkait 
• Seperti metode contoh, metode statis sanggup diwariskan. Namun,metode statis tidak bisa diganti Jika metode statis yang didefinisikan dalam superclass didefinisikan ulang dalam a subclass, metode yang
didefinisikan dalam superclass disembunyikan. Metode statis tersembunyi bisa dipanggil memakai sintaks SuperClassName.staticMethodName.

Overriding vs Overloading

Anda telah berguru wacana metode overloading di § 5.8. Overloading berarti mendefinisikan multiple metode dengan nama yang sama tapi berbeda tanda tangan. Override berarti memperlihatkan yang gres implementasi untuk metode di subclass. Metode ini sudah didefinisikan dalam superclass. 
Untuk menimpa metode, metode harus didefinisikan di subclass dengan memakai tanda tangan yang sama dan jenis pengembalian yang sama. 
Mari kita gunakan sebuah pola untuk memperlihatkan perbedaan antara overriding dan overloading. Di sebuah) Di bawah, metode p (double i) di kelas A menggantikan metode yang sama yang didefinisikan di kelas B. Di (b), bagaimanapun, kelas B mempunyai dua metode kelebihan beban p (double i) dan p (int i). Itu Metode p (double i) diwarisi dari B.
Gambar 6
Saat Anda menjalankan kelas Uji pada (a), keduanya a.p (10) dan a.p (10.0) memanggil p (ganda i) metode yang didefinisikan di kelas A untuk menampilkan 10.0. Saat Anda menjalankan kelas Uji di (b), a.p (10) memanggil metode p (int i) yang didefinisikan di kelas B untuk menampilkan 20, dan a.p (10.0) memanggil p (double i) yang didefinisikan di kelas A untuk menampilkan 10.0.

Objek Obyek dan Metode toString () nya

Setiap kelas di Jawa diturunkan dari kelas java.lang.Object. Jika tidak ada warisan ditentukan ketika kelas didefinisikan, superclass kelas ialah Object secara default. Sebagai contoh, dua definisi kelas berikut ialah sama:

Gambar 7
Kelas menyerupai String, StringBuilder, Loan, dan GeometricObject secara implisit ialah subclass Objek (seperti juga semua kelas utama yang pernah Anda lihat di buku ini sejauh ini). Itu penting untuk mengenal metode yang diberikan oleh kelas Objek sehingga Anda sanggup menggunakannya di komputer Anda kelas. Kami akan mengenalkan metode toString di kelas Object di cuilan ini.
Tanda tangan dari metode toString () adalah
public String toString() 

Meminta toString () pada sebuah objek mengembalikan sebuah string yang menggambarkan objek. Secara default, itu mengembalikan sebuah string yang terdiri dari sebuah nama kelas yang objeknya ialah sebuah instance, sebuah tanda (@), dan alamat memori objek dalam heksadesimal. Misalnya, perhatikan instruksi berikut untuk kelas Pinjaman yang didefinisikan pada 

Listing 10: 
Loan loan = new Loan(); 
System.out.println(loan.toString());

Kode menampilkan sesuatu menyerupai Loan @ 15037e5. Pesan ini tidak terlalu membantu atau informatif. Biasanya Anda harus mengganti metode toString sehingga mengembalikan deskriptif string representasi objek. Misalnya, metode toString di kelas Object diganti dalam kelas GeometricObject pada baris 46-49 pada 
Listing 11 sebagai berikut:
public String toString() {
return "created on " + dateCreated + "\ncolor: " + color +
" and filled: " + filled;
}

Polimorfisme

Tiga pilar pemrograman berorientasi objek ialah enkapsulasi, pewarisan, dan polimorfisme. Anda telah mempelajari dua yang pertama. Bagian ini memperkenalkan polimorfisme. 
Pertama mari kita definisikan dua istilah yang berguna: subtype dan supertype. Sebuah kelas mendefinisikan sebuah tipe. Sebuah tipe didefinisikan oleh subclass disebut subtipe dan tipe yang didefinisikan oleh superclass-nya disebut supertype. Jadi, bisa dibilang bahwa Circle ialah subtype dari GeometricObject dan GeometricObject ialah a supertype untuk Circle 
Hubungan warisan memungkinkan subclass mewarisi fitur dari superclass-nya suplemen fitur gres Subclass ialah spesialisasi superclass; setiap pola a Subclass juga merupakan instance dari superclass-nya, tapi tidak sebaliknya. Misalnya, setiap bulat ialah a Benda geometris, tapi tidak setiap benda geometris berbentuk lingkaran. Karena itu, kau selalu bisa lewat pola subclass ke parameter tipe superclass-nya. Perhatikan instruksi pada Listing 11.

LISTING 11 PolymorphismDemo.java 

1 public class PolymorphismDemo {
2 /** Main method */
3 public static void main(String[] args) {
4 // Display circle and rectangle properties
5 displayObject(new Circle4(1, "red", false));
6 displayObject(new Rectangle1(1, 1, "black", true));
7 }
8
9 /** Display geometric object properties */
10 public static void displayObject(GeometricObject1 object){
11 System.out.println("Created on " + object.getDateCreated() +
12 ". Color is " + object.getColor());
13 }
14 }

Created on Mon Mar 09 19:25:20 EDT 2009. Color is white 
Created on Mon Mar 09 19:25:20 EDT 2009. Color is black

Metode displayObject (baris 10) mengambil parameter tipe GeometricObject. Kamu sanggup meminta displayObject dengan melewatkan instance GeometricObject (mis., Circle4 gres 1, "merah", salah) dan Rectangle1 gres (1, 1, "hitam", salah) pada baris 5-6). Sebuah Objek subkelas sanggup dipakai dimanapun benda superclassnya digunakan. Hal ini biasa diketahui sebagai polimorfisme (dari kata Yunani yang berarti "banyak bentuk"). Secara sederhana, polimorfisme berarti bahwa variabel supertype sanggup merujuk ke objek subtipe.

Dynamic Binding

Sebuah metode sanggup didefinisikan dalam superclass dan diganti di subclassnya. Misalnya, toString () method didefinisikan di kelas Object dan diganti dalam GeometricObject1. Pertimbangkan instruksi berikut ini:
Object o = new GeometricObject();
System.out.println(o.toString());

Metode toString () mana yang dipanggil oleh o? Untuk menjawab pertanyaan ini, pertama kami perkenalkan dua istilah: tipe dan jenis yang dideklarasikan. Variabel harus dinyatakan sebagai tipe. Jenis variabel disebut tipe yang dideklarasikan. Tipe yang dinyatakan di sini ialah Object. Variabel acuan tipe sanggup menyimpan nilai null atau acuan ke instance dari tipe yang dideklarasikan. Contohnya sanggup dibentuk dengan memakai konstruktor tipe yang dideklarasikan atau subtipenya. Jenis sebetulnya dari Variabel ialah kelas faktual untuk objek yang direferensikan oleh variabel. Inilah tipe sebetulnya GeometricObject, alasannya ialah o acuan ke objek yang dibentuk memakai GeometricObject gres (). Metode toString () mana yang dipanggil oleh o ditentukan oleh tipe faktual o. Ini dikenal sebagai dynamic binding. Pengikatan dinamis bekerja sebagai berikut: Misalkan sebuah objek ialah turunan dari kelas C1, C2, Cn-1, dan Cn, di mana C1 ialah subkelas dari C2, C2 ialah subkelas C3, dan Cn-1 ialah subkelas dari Cn, menyerupai yang ditunjukkan pada Gambar 11.2. Artinya, Cn ialah kelas yang paling umum, dan C1 ialah yang paling spesifik

Gambar 8 Metode yang akan dipanggil secara dinamis terikat pada ketika runtime
kelas. Di Jawa, Cn ialah kelas Object. Jika kita memanggil metode p, JVM mencari implementasinya untuk metode p di C1, C2, Cn-1, dan Cn, dalam urutan ini, hingga ditemukan. Sekali a implementasi ditemukan, pencarian berhenti dan implementasi yang pertama ditemukan dipanggil. Listing 11.6 memberi pola untuk memperlihatkan dynamic binding. 

LISTING 6 DynamicBindingDemo.java 

1 public class DynamicBindingDemo {
2 public static void main(String[] args) {
3 m(new GraduateStudent());
4 m(new Student());
5 m(new Person());
6 m(new Object());
7 }
8
9 public static void m(Object x) {
10 System.out.println(x.toString());
11 }
12 }
13
14 class GraduateStudent extends Student{
15 }
16
17 class Student extends Person {
18 public String toString()
{
19 return "Student";
20 }
21 }
22
23 class { Person extends Object
24 public String { toString()
25 return "Person";
26 }
27 }


Student 
Student 
Person 
java.lang.Object@130c19b 

Metode m (baris 9) mengambil parameter dari tipe Objek. Anda bisa memanggil m dengan objek apapun (misalnya, GraduateStudent gres (), Siswa gres (), Orang gres (), dan Objek gres ()) di garis 3-6). 
Bila metode m (Object x) dieksekusi, metode tostring toxing ialah x dipanggil x mungkin merupakan pola dari GraduateStudent, Student, Person, atau Object. Kelas GraduateStudent, Student, Person, and Object mempunyai implementasi sendiri metode toString Implementasi yang dipakai akan ditentukan oleh tipe faktual x di runtime 
Memohon m (GraduateStudent gres ()) (baris 3) mengakibatkan metode toString didefinisikan di kelas Siswa untuk dipanggil. Memohon m (Student baru) (baris 4) mengakibatkan metode toString didefinisikan di Kelas siswa dipanggil. 
Memohon m (Person baru) (baris 5) mengakibatkan metode toString didefinisikan dalam Person kelas yang akan dipanggil. 
Invoking m (new Object ()) (baris 6) mengakibatkan metode toString didefinisikan di kelas Objek untuk dipanggil. 
Mencocokkan sebuah metode tanda tangan dan mengikat suatu metode implementasi dua terpisah masalah. Variabel acuan yang dinyatakan memilih metode mana yang cocok dengan kompilasi waktu. Kompilator menemukan metode yang sesuai berdasarkan jenis parameter, jumlah parameter, dan urutan parameter pada waktu kompilasi. Sebuah metode sanggup diimplementasikan di beberapa subclass. JVM secara dinamis mengikat implementasi metode ketika runtime, diputuskan oleh jenis variabel yang sebenarnya.

Objek Casting dan instance dari Operator

Anda telah memakai operator casting untuk mengubah variabel dari satu jenis primitif lain. Pengecoran juga sanggup dipakai untuk mengubah objek dari satu tipe kelas ke kelas lainnya hirarki warisan Di cuilan sebelumnya, pernyataan tersebut
m(new Student());
Menugaskan objek Siswa gres () ke parameter tipe Objek. Pernyataan ini setara dengan
Object o = new Student(); // Implicit casting m(o); 
 Pernyataan Object o = new Student (), yang dikenal sebagai implisit casting, ialah legal alasannya ialah a Contoh Student secara otomatis merupakan instance dari Object. Misalkan Anda ingin memutuskan acuan objek o ke variabel tipe Siswa memakai pernyataan berikut:
Student b = o;
Dalam hal ini terjadi kesalahan kompilasi. Mengapa pernyataan Object o = new Student () bekerja tapi Siswa b = o tidak? Alasannya ialah bahwa objek Siswa selalu a pola Objek, tapi Objek tidak harus merupakan instance dari Siswa. Meskipun Anda bisa melihat bahwa o benar-benar objek Siswa, compiler tidak cukup pintar untuk mengetahuinya. Untuk Katakan pada kompiler bahwa o ialah objek Siswa, gunakan casting eksplisit. Sintaksnya menyerupai dengan yang dipakai untuk casting antara tipe data primitif. Lampirkan tipe objek sasaran dalam tanda kurung dan letakkan sebelum objek dilemparkan, sebagai berikut:
Student b = (Student)o; // Explicit casting 
Selalu memungkinkan untuk melemparkan sebuah instance dari subclass ke variabel superclass (dikenal sebagai upcasting), alasannya ialah sebuah instance dari subclass selalu merupakan instance dari superclass-nya. Kapan casting sebuah instance dari superclass ke variabel subkelasnya (dikenal sebagai downcasting), casting eksplisit harus dipakai untuk mengkonfirmasi niat Anda ke compiler dengan (SubclassName) cor notasi. Agar casting berhasil, Anda harus memastikan bahwa Objek yang akan dilemparkan ialah turunan dari subkelas. Jika objek superclass bukan merupakan instance dari subclass, sebuah ClassCastException runtime terjadi. Misalnya, jikalau sebuah objek bukan sebuah Contoh Siswa, tidak sanggup dilemparkan ke dalam variabel Siswa. Ini ialah praktik yang baik, oleh alasannya ialah itu, untuk memastikan bahwa objek ialah turunan objek lain sebelum mencoba casting. Ini sanggup dilakukan dengan memakai instanceof operator. Pertimbangkan instruksi berikut ini:

Object myObject = new Circle();
... // Beberapa baris kode
/** Perform casting if myObject is an instance of Circle */
if (myObject instanceof Circle) {
System.out.println("The circle diameter is " +
((Circle)myObject).getDiameter());
...
}


Anda mungkin bertanya-tanya mengapa casting diperlukan. Variabel myObject dideklarasikan Object. Tipe yang dideklarasikan memilih metode mana yang cocok pada waktu kompilasi. 
Menggunakan myObject.getDiameter () akan mengakibatkan kesalahan kompilasi, alasannya ialah kelas Object tidak tidak mempunyai metode getDiameter Kompilator tidak sanggup menemukan kecocokan untuk myObject.getDiameter (). 
Hal ini diharapkan untuk melemparkan myObject ke dalam tipe Circle untuk diceritakan kompiler yang myObject juga merupakan instance dari Circle. 
Mengapa tidak mendefinisikan myObject sebagai tipe Circle di daerah pertama? Untuk mengaktifkan pemrograman generik, Ini ialah praktik yang baik untuk mendefinisikan variabel dengan supertype, yang sanggup mendapatkan nilai dari subtipe apapun. 
Listing 11.7 memperlihatkan polimorfisme dan casting. Program ini membuat dua objek (baris 5-6), bulat dan persegi panjang, dan memanggil metode displayObject untuk menampilkannya (baris 9-10). Metode displayObject menampilkan area dan diameter jikalau objeknya ialah a bulat (garis 15), dan area jikalau benda berbentuk persegi panjang (garis 21). 
LISTING 7 CastingDemo.java

1 public class CastingDemo {
2 /** Main method */
3 public static void main(String[] args) {
4 // Create and initialize two objects
5 Object object1 = new Circle4(1);
6 Object object2 = new Rectangle1(1, 1);
7
8 // Display circle and rectangle
9 displayObject(object2);
10 displayObject(object1);
11 }
12
13 /** A method for displaying an object */
14 public static void displayObject(Object object){
15 if(object instanceof Circle4) {
16 System.out.println("The circle area is " +
17 ((Circle4)object).getArea());
18 System.out.println("The circle diameter is " +
19 ((Circle4)object).getDiameter());
20 }
21 else if object instanceof Rectangle1 ( ) {
22 System.out.println("The rectangle area is " +
23 ((Rectangle1)object).getArea());
24 }
25 }
26 }

Daerah bulat ialah 3.141592653589793
Diameter bulat ialah 2.0
Area persegi panjang ialah 1.0

Metode displayObject (Object object) ialah pola pemrograman generik. Saya t sanggup dipanggil dengan melewatkan instance Objek.
 Program ini memakai casting implisit untuk memutuskan objek Circle ke object1 dan a Rectangle object ke object2 (baris 5-6), kemudian memanggil metode displayObject untuk ditampilkan informasi wacana benda-benda ini (baris 9-10). 
Dalam metode displayObject (baris 14-25), casting eksplisit dipakai untuk mentransmisikan objek Lingkari jikalau objek itu ialah instance dari Circle, dan metode getArea dan getDiameter dipakai untuk menampilkan area dan diameter lingkaran. 
Pengecoran hanya bisa dilakukan bila objek sumber ialah turunan dari kelas target. Program memakai instanceof operator untuk memastikan bahwa objek sumber ialah turunan dari sasaran kelas sebelum melaksanakan pengecoran (baris 15). 
Tembakan eksplisit ke Lingkaran (baris 17, 19) dan Persegi Panjang (baris 23) diharapkan alasannya ialah Metode getArea dan getDiameter tidak tersedia di kelas Object.

Objeknya Sama dengan Metode

Metode lain yang didefinisikan dalam kelas Object yang sering dipakai ialah metode yang sama. Nya tanda tangan ialah
public boolean equals(Object o)
Metode ini menguji apakah dua objek sama. Sintaks untuk memanggilnya adalah:
object1.equals(object2); 
Implementasi default metode sama dengan kelas Objek adalah:
public boolean equals(Object obj) {
return (this == obj);
}

Implementasi ini mengusut apakah dua variabel acuan menunjuk ke objek yang sama dengan yang dipakai operator == Anda harus mengganti metode ini di kelas khusus Anda untuk menguji apakah ada dua perbedaan benda mempunyai konten yang sama 
Anda telah memakai metode yang sama untuk membandingkan dua senar di § 9.2, "The String Kelas. "Metode yang sama dengan kelas String diwarisi dari kelas Objek dan diganti di kelas String untuk menguji apakah dua senar identik dalam konten. Kamu bisa Ganti metode sama dengan kelas Lingkaran untuk membandingkan apakah dua bulat sama berdasarkan radius mereka sebagai berikut:

 public boolean equals(Object o) {
if (o instanceof Circle) {
return radius == ((Circle)o).radius;
}
else
return false;}

 Kelas ArrayList

Sekarang kita siap mengenalkan kelas yang sangat berkhasiat untuk menyimpan objek. Anda bisa membuat array untuk menyimpan benda Tapi, begitu array dibuat, ukurannya tetap. Java menyediakan ArrayList kelas yang bisa dipakai untuk menyimpan jumlah objek yang tidak terbatas. Gambar 9 memperlihatkan beberapa metode di ArrayList
Gambar 9

LISTING 8 TestArrayList.java 
1 public class TestArrayList {
2 public static void main(String[] args) {
3 // Create a list to store cities
4 java.util.ArrayList cityList = new java.util.ArrayList();
5
6 // Add some cities in the list
7 cityList.add("London");
8 // cityList now contains [London]
9 cityList.add("Denver");
10 // cityList now contains [London, Denver]
11 cityList.add("Paris");
12 // cityList now contains [London, Denver, Paris]
13 cityList.add("Miami");
14 // cityList now contains [London, Denver, Paris, Miami]
15 cityList.add("Seoul");
16 // contains [London, Denver, Paris, Miami, Seoul]
17 cityList.add("Tokyo");
18 // contains [London, Denver, Paris, Miami, Seoul, Tokyo]
19
20 System.out.println("List size? "+ cityList.size() );
21 System.out.println("Is Miami in the list? " +
22 cityList.contains("Miami");
23 System.out.println("The location of Denver in the list? "
24 + cityList.indexOf("Denver"));
25 System.out.println("Is the list empty? " +
26 cityList.isEmpty()); // Print false
27
28 // Insert a new city at index 2
29 cityList.add(2, "Xian");
30 // contains [London, Denver, Xian, Paris, Miami, Seoul, Tokyo]
31
32 // Remove a city from the list
33 cityList.remove("Miami");
34 // contains [London, Denver, Xian, Paris, Seoul, Tokyo]
35
36 // Remove a city at index 1
37 cityList.remove(1);
38 // contains [London, Xian, Paris, Seoul, Tokyo]
39
40 // Display the contents in the list
41 System.out.println(cityList.toString());
42
43 // Display the contents in the list in reverse order
44 for (int i = cityList.size() - 1; i >= 0; i--)
45 System.out.print(cityList.get(i)+ " ");
46 System.out.println();
47
48 // Create a list to store two circles
49 java.util.ArrayList list = new java.util.ArrayList();
50
51 // Add two circles
52 list.add(new Circle4(2));
53 list.add(new Circle4(3));
54
55 // Display the area of the first circle in the list
56 System.out.println("The area of the circle? " +
57 ((Circle4)list.get(0)).getArea());
58 }
59 }

Program ini membuat ArrayList memakai konstruktor no-arg (baris 4).
Metode menambahkan menambahkan instance Object ke dalam daftar.
Karena String ialah subkelas dari Object, string bisa ditambahkan ke daftar
Metode menambahkan (baris 7-17) menambahkan objek ke selesai daftar.
Jadi, sehabis cityList.add ("London") (baris 7), daftarnya berisi
[London]
Setelah citylist tambahkan ("Denver") (baris 9), daftarnya berisi
[London, Denver]
Setelah menambahkan Paris, Miami, Seoul, dan Tokyo (baris 11-17), daftar
berisi
[London, Denver, Paris, Miami, Seoul, Tokyo]
Invoking size () (line 20) mengembalikan ukuran daftar, yang ketika ini 6.
Invoking berisi ("Miami") (baris 22) mengusut apakah objek ada dalam
daftar. Dalam kasus ini, ia kembali Benar, alasannya ialah Miami masuk dalam
daftar. Memohon indexOf ("Denver") (baris 24) mengembalikan indeks dari
objek dalam daftar, yaitu 1. Jika objek tidak ada dalam daftar, ia
mengembalikan -1. IsEmpty () metode (baris 26) mengusut apakah daftar
itu kosong Ini mengembalikan false, alasannya ialah daftarnya tidak kosong.
Pernyataan cityList.add (2, "Xian") (baris 29) memasukkan sebuah objek ke 
dalam daftar di indeks yang ditentukan Setelah pernyataan ini, daftarnya
menjadi
[London, Denver, Xian, Paris, Miami, Seoul, Tokyo]
Pernyataan citylist hapus ("Miami") (baris 33) menghapus objek dari daftar.
Setelah pernyataan ini, daftarnya menjadi
[London, Denver, Xian, Paris, Seoul, Tokyo]
Pernyataan citylist hapus (1) (baris 37) menghapus objek pada indeks yang
ditentukan dari daftar Setelah pernyataan ini, daftarnya menjadi
[London, Xian, Paris, Seoul, Tokyo]
Pernyataan di baris 41 sama dengan
System.out.println (cityList);
Metode toString () mengembalikan representasi string untuk daftar dalam
bentuk [e0.toString (), e1.toString (), ..., ek.toString ()], di mana e0, e1, dan
ek ialah unsur-unsur dalam daftar. Metode get (index) (baris 45)
mengembalikan objek pada indeks yang ditentukan.
Objek ArrayList bisa dipakai menyerupai array, tapi ada banyak
perbedaan. Tabel 11.1 daftar kesamaan dan perbedaan mereka
Begitu sebuah array dibuat, ukurannya tetap. Anda sanggup mengakses
elemen array dengan memakai notasi kuadrat-persegi (misalnya,
sebuah [indeks]). Saat ArrayList dibuat, ukurannya ialah 0. Anda tidak
bisa memakai metode get dan set jikalau elemen tidak ada dalam daftar.
Praktis untuk menambahkan, menyisipkan,


dan hapus elemen dalam daftar, tapi agak rumit untuk menambahkan, menyisipkan, dan menghapus elemen sebuah array Anda harus menulis instruksi untuk memanipulasi array supaya bisa melaksanakan operasi ini.

Kelas Stack Kustom

"Merancang Kelas untuk Tumpukan" di §10.8 menyajikan kelas stack untuk menyimpan nilai int. Ini Bagian mengenalkan kelas stack untuk menyimpan objek. Anda bisa memakai ArrayList untuk diimplementasikan Stack, menyerupai yang ditunjukkan pada Listing 9. Diagram UML untuk kelas ditunjukkan pada Gambar 10

Gambar Kelas MyStack mengenkapsulasi tumpukan penyimpanan dan menyediakan operasinya untuk memanipulasi tumpukan.

LISTING 9 MyStack.java

1 public class MyStack {
2 private java.util.ArrayList list = new java.util.ArrayList();
3
4 public boolean isEmpty(){
5 return list.isEmpty();
6 }
7
8 public int getSize(){
9 return list.size();
10 }
11
12 public Object peek() {
13 return list.get(getSize() - 1);
14 }
15
16 public Object pop(){
17 Object o = list.get(getSize() - 1);
18 list.remove(getSize() - 1);
19 return o;
20 }
21
22 public void push(Object o) {
23 list.add(o);
24 }
25
26 public int search(Object o){
27 return list.lastIndexOf(o);
28 }
29
30 /** Override the toString in the Object class */
31 public String toString() {
32 return "stack: " + list.toString();
33 }
34 }

Daftar array dibentuk untuk menyimpan elemen di stack (baris 2). Metode isEmpty () (baris 4-6) mengembalikan daftar.isEmpty (). Metode getSize () (baris 8-10) kembali list.size (). Metode mengintip () (garis 12-14) mengambil elemen di cuilan atas tumpukan tanpa menghapusnya Akhir daftar ialah cuilan atas tumpukan. Metode pop () (baris 16-20) menghilangkan elemen atas dari tumpukan dan mengembalikannya. Dorongan (elemen Obyek)Metode (baris 22-24) menambahkan elemen yang ditentukan ke stack. Pencarian (elemen Obyek) Metode mengusut apakah elemen yang ditentukan ada di stack, dan mengembalikan indeks elemen pencocokan pertama di tumpukan dari atas dengan memohon daftar.lastIndexOf (o). Itu toString () method (baris 31-33) yang didefinisikan di kelas Object diganti untuk menampilkan isi tumpukan dengan memohon list.toString (). Metode toString () diterapkan di ArrayList mengembalikan representasi string dari semua elemen dalam daftar array.