pengertian dan contoh program dari Inheritance & Polymorphism

pengertian dan contoh program dari Inheritance & Polymorphism

Introduction

Pemrograman berorientasi objek memungkinkan Anda memperoleh kelas baru dari kelas yang ada. Ini adalah disebut warisan Warisan adalah fitur penting dan kuat di Java untuk menggunakan kembali perangkat lunak. Misalkan Anda mendefinisikan kelas pada lingkaran model, persegi panjang, dan segitiga. Ini kelas memiliki banyak fitur umum. Apa cara terbaik untuk mendesain kelas-kelas ini agar terhindar redundansi dan membuat sistem mudah dipahami dan mudah perawatannya? Jawabannya adalah gunakan pewarisan.

Superclasses and Subclasses

Anda menggunakan kelas untuk memodelkan objek dengan tipe yang sama. Kelas yang berbeda mungkin memiliki 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 seperti lingkaran dan persegi panjang. Benda geometris memiliki banyak sifat umum dan perilaku. Mereka bisa digambar dengan warna tertentu, terisi atau terisi. Jadi kelas umum

 Gambar 1

GeometricObject dapat digunakan untuk memodelkan semua objek geometris. Kelas ini berisi properti warna dan isi dan sesuai mereka dapatkan dan tetapkan metode. Asumsikan bahwa kelas ini juga berisi properti tanggalCreated dan metode getDateCreated () dan toString (). Metode toString () mengembalikan representasi string untuk objek. Karena lingkaran itu istimewa Jenis objek geometris, ia berbagi sifat dan metode yang sama dengan benda geometris lainnya. Jadi, masuk akal untuk menentukan kelas Lingkaran yang memperluas kelas GeometrikObject. Juga, Rectangle juga dapat dinyatakan sebagai subclass dari GeometricObject. Gambar 1 menunjukkan hubungan antara kelas-kelas ini. Panah yang menunjuk ke superclass digunakan untuk menunjukkan hubungan 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 dapat 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 dapat diakses dari Geometric-Kelas objek Selain itu, ia memiliki 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 mudah diakses dari Kelas GeometrikObject Selain itu, ia memiliki lebar dan tinggi bidang data dan yang terkait mendapatkan dan menetapkan 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 menggunakan 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 digunakan di kelas turunan. Anda mungkin mencoba untuk menggunakan warna bidang data dan langsung 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, karena bidang data pribadi berwarna dan terisi pada Geometric-Kelas objek tidak dapat diakses di kelas manapun selain di kelas GeometricObject diri. Satu-satunya cara untuk membaca dan memodifikasi warna dan isi adalah melalui cara mendapatkan dan mengaturnya metode. 

Kelas Rectangle (Listing 3) memperluas kelas GeometricObject (Listing 2) menggunakan 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 menciptakan 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 dibuat pada Jum 24 Sep 20:31:02 EDT 2009
warna: putih dan penuh: salah
Jari-jarinya adalah 1.0
Daerahnya adalah 3.141592653589793
Diameternya 2.0
Sebuah persegi panjang dibuat pada Kamis 24 Sep 20:31:02 EDT 2009
warna: putih dan penuh: salah
Wilayahnya 8,0
Perimeter adalah 12.0

Hal-hal berikut tentang 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 dapat diakses di luar
kelas. Oleh karena itu, mereka tidak bisa digunakan langsung di
subclass. Namun, mereka dapat diakses / dimutasi melalui accessor
/ mutator publik jika didefinisikan dalam superclass. Tidak semuahubungan
harus dimodelkan menggunakan pewarisan. Misalnya, a
persegi adalah persegi panjang, tapi sebaiknya Anda tidak
menentukan kelas Square untuk memperpanjang a. Rectangle class,
karena 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 digunakan untuk memodelkan is-a relationship. Jangan
membabi buta memperpanjang kelas saja demi penggunaan kembali
metode. Misalnya, tidak masuk akal untuk kelas Pohon
memperpanjang kelas Person, meskipun mereka memiliki sifat
umum seperti tinggi badan dan berat. Sebuah subclass dan
superclass-nya pasti memiliki 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 dapat mewarisi langsung dari hanya satu
superclass. Ini Pembatasan dikenal sebagai single inheritance. Jika
Anda menggunakan 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 dapat 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 referensi memanggil objek Kata kunci super mengacu pada superclass
kelas di mana super muncul Ini bisa digunakan 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 adalah satu-satunya cara untuk secara eksplisit memanggil konstruktor superkelas. Misalnya, konstruktor pada baris 11-15 pada Listing 11.2 dapat diganti dengan kode berikut:

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

Constructor Chaining

Konstruktor dapat 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 melakukan tugasnya sendiri. Jika superclass adalah berasal dari kelas lain, konstruktor superclass memanggil konstruktor kelas induknya sebelum melakukan tugasnya sendiri. Proses ini berlanjut sampai konstruktor terakhir sepanjang hirarki pewarisan disebut ini adalah penjilidan konstruktor. 

Pertimbangkan kode 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 tugas Orang
(2) Buat konstruktor karyawan yang kelebihan beban
(3) Melakukan tugas Pegawai
(4) Melakukan tugas Fakultas

Program ini menghasilkan output sebelumnya. Mengapa? Mari kita bahas alasannya. Sejalan 3, baru Fakultas () memanggil konstruktor no-arg dari Fakultas. Karena fakultas adalah 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 adalah 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 memberikan konstruktor tanpa argumen untuk menghindari pemrograman kesalahan Pertimbangkan kode 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 adalah subclass Fruit, konstruktor default Apple secara otomatis memanggil konstruktor no-arg Fruit. Namun, Buah tidak memiliki konstruktor no-arg, karena Buah memiliki konstruktor eksplisit yang didefinisikan. Karena itu, program tidak bisa dikompilasi. Panduan Desain Lebih baik memberi konstruktor no-arg (jika diinginkan) untuk setiap kelas agar kelas mudah memperpanjang dan untuk menghindari kesalahan.

Memanggil Metode Superclass

Kata kunci super juga bisa digunakan untuk referensi metode selain konstruktor di superclass Sintaksnya seperti 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, karena getDateCreated adalah metode di kelas GeometricObject dan diwarisi oleh Lingkari kelas. Namun demikian, dalam beberapa kasus, seperti yang ditunjukkan pada bagian berikutnya, kata kunci super sangat dibutuhkan

Overriding Methods

Subclass mewarisi metode dari superclass. Terkadang diperlukan 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 dapat diganti untuk mengembalikan representasi string untuk a lingkaran. Untuk mengesampingkannya, tambahkan metode 
baru 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 digunakan 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 menggunakan sintaks seperti super.super.toString ()? Tidak. Ini adalah kesalahan sintaksis.
Beberapa poin patut diperhatikan:
• Metode contoh dapat diganti hanya jika dapat diakses. Jadi metode pribadi tidak bisa ditimpa, karena 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 dapat 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 menggunakan sintaks SuperClassName.staticMethodName.

Overriding vs Overloading

Anda telah belajar tentang metode overloading di § 5.8. Overloading berarti mendefinisikan multiple metode dengan nama yang sama tapi berbeda tanda tangan. Override berarti memberikan yang baru implementasi untuk metode di subclass. Metode ini sudah didefinisikan dalam superclass. 
Untuk menimpa metode, metode harus didefinisikan di subclass dengan menggunakan tanda tangan yang sama dan jenis pengembalian yang sama. 
Mari kita gunakan sebuah contoh untuk menunjukkan 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 memiliki 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 adalah Object secara default. Sebagai contoh, dua definisi kelas berikut adalah sama:

Gambar 7
Kelas seperti String, StringBuilder, Loan, dan GeometricObject secara implisit adalah 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 dapat menggunakannya di komputer Anda kelas. Kami akan mengenalkan metode toString di kelas Object di bagian 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 adalah sebuah instance, sebuah tanda (@), dan alamat memori objek dalam heksadesimal. Misalnya, perhatikan kode berikut untuk kelas Pinjaman yang didefinisikan pada 

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

Kode menampilkan sesuatu seperti 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 adalah 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 adalah subtype dari GeometricObject dan GeometricObject adalah a supertype untuk Circle 
Hubungan warisan memungkinkan subclass mewarisi fitur dari superclass-nya tambahan fitur baru Subclass adalah spesialisasi superclass; setiap contoh a Subclass juga merupakan instance dari superclass-nya, tapi tidak sebaliknya. Misalnya, setiap lingkaran adalah a Benda geometris, tapi tidak setiap benda geometris berbentuk lingkaran. Karena itu, kamu selalu bisa lewat contoh subclass ke parameter tipe superclass-nya. Perhatikan kode 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 dapat meminta displayObject dengan melewatkan instance GeometricObject (mis., Circle4 baru 1, "merah", salah) dan Rectangle1 baru (1, 1, "hitam", salah) pada baris 5-6). Sebuah Objek subkelas dapat digunakan dimanapun benda superclassnya digunakan. Hal ini biasa diketahui sebagai polimorfisme (dari kata Yunani yang berarti "banyak bentuk"). Secara sederhana, polimorfisme berarti bahwa variabel supertype dapat merujuk ke objek subtipe.

Dynamic Binding

Sebuah metode dapat didefinisikan dalam superclass dan diganti di subclassnya. Misalnya, toString () method didefinisikan di kelas Object dan diganti dalam GeometricObject1. Pertimbangkan kode 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 adalah Object. Variabel referensi tipe dapat menyimpan nilai null atau referensi ke instance dari tipe yang dideklarasikan. Contohnya dapat dibuat dengan menggunakan konstruktor tipe yang dideklarasikan atau subtipenya. Jenis sebenarnya dari Variabel adalah kelas aktual untuk objek yang direferensikan oleh variabel. Inilah tipe sebenarnya GeometricObject, karena o referensi ke objek yang dibuat menggunakan GeometricObject baru (). Metode toString () mana yang dipanggil oleh o ditentukan oleh tipe aktual o. Ini dikenal sebagai dynamic binding. Pengikatan dinamis bekerja sebagai berikut: Misalkan sebuah objek adalah turunan dari kelas C1, C2, Cn-1, dan Cn, di mana C1 adalah subkelas dari C2, C2 adalah subkelas C3, dan Cn-1 adalah subkelas dari Cn, seperti yang ditunjukkan pada Gambar 11.2. Artinya, Cn adalah kelas yang paling umum, dan C1 adalah yang paling spesifik

Gambar 8 Metode yang akan dipanggil secara dinamis terikat pada saat runtime
kelas. Di Jawa, Cn adalah kelas Object. Jika kita memanggil metode p, JVM mencari implementasinya untuk metode p di C1, C2, Cn-1, dan Cn, dalam urutan ini, sampai ditemukan. Sekali a implementasi ditemukan, pencarian berhenti dan implementasi yang pertama ditemukan dipanggil. Listing 11.6 memberi contoh untuk menunjukkan 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 baru (), Siswa baru (), Orang baru (), dan Objek baru ()) di garis 3-6). 
Bila metode m (Object x) dieksekusi, metode tostring toxing adalah x dipanggil x mungkin merupakan contoh dari GraduateStudent, Student, Person, atau Object. Kelas GraduateStudent, Student, Person, and Object memiliki implementasi sendiri metode toString Implementasi yang digunakan akan ditentukan oleh tipe aktual x di runtime 
Memohon m (GraduateStudent baru ()) (baris 3) menyebabkan metode toString didefinisikan di kelas Siswa untuk dipanggil. Memohon m (Student baru) (baris 4) menyebabkan metode toString didefinisikan di Kelas siswa dipanggil. 
Memohon m (Person baru) (baris 5) menyebabkan metode toString didefinisikan dalam Person kelas yang akan dipanggil. 
Invoking m (new Object ()) (baris 6) menyebabkan metode toString didefinisikan di kelas Objek untuk dipanggil. 
Mencocokkan sebuah metode tanda tangan dan mengikat suatu metode implementasi dua terpisah masalah. Variabel referensi yang dinyatakan menentukan metode mana yang cocok dengan kompilasi waktu. Kompilator menemukan metode yang sesuai menurut jenis parameter, jumlah parameter, dan urutan parameter pada waktu kompilasi. Sebuah metode dapat diimplementasikan di beberapa subclass. JVM secara dinamis mengikat implementasi metode saat runtime, diputuskan oleh jenis variabel yang sebenarnya.

Objek Casting dan instance dari Operator

Anda telah menggunakan operator casting untuk mengubah variabel dari satu jenis primitif lain. Pengecoran juga dapat digunakan untuk mengubah objek dari satu tipe kelas ke kelas lainnya hirarki warisan Di bagian sebelumnya, pernyataan tersebut
m(new Student());
Menugaskan objek Siswa baru () 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, adalah legal karena a Contoh Student secara otomatis merupakan instance dari Object. Misalkan Anda ingin menetapkan referensi objek o ke variabel tipe Siswa menggunakan pernyataan berikut:
Student b = o;
Dalam hal ini terjadi kesalahan kompilasi. Mengapa pernyataan Object o = new Student () bekerja tapi Siswa b = o tidak? Alasannya adalah bahwa objek Siswa selalu a contoh 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 adalah objek Siswa, gunakan casting eksplisit. Sintaksnya mirip dengan yang digunakan untuk casting antara tipe data primitif. Lampirkan tipe objek target 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), karena 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 digunakan untuk mengkonfirmasi niat Anda ke compiler dengan (SubclassName) cor notasi. Agar casting berhasil, Anda harus memastikan bahwa Objek yang akan dilemparkan adalah turunan dari subkelas. Jika objek superclass bukan merupakan instance dari subclass, sebuah ClassCastException runtime terjadi. Misalnya, jika sebuah objek bukan sebuah Contoh Siswa, tidak dapat dilemparkan ke dalam variabel Siswa. Ini adalah praktik yang baik, oleh karena itu, untuk memastikan bahwa objek adalah turunan objek lain sebelum mencoba casting. Ini dapat dilakukan dengan menggunakan instanceof operator. Pertimbangkan kode 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 menentukan metode mana yang cocok pada waktu kompilasi. 
Menggunakan myObject.getDiameter () akan menyebabkan kesalahan kompilasi, karena kelas Object tidak tidak memiliki metode getDiameter Kompilator tidak dapat menemukan kecocokan untuk myObject.getDiameter (). 
Hal ini diperlukan 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 tempat pertama? Untuk mengaktifkan pemrograman generik, Ini adalah praktik yang baik untuk mendefinisikan variabel dengan supertype, yang dapat menerima nilai dari subtipe apapun. 
Listing 11.7 menunjukkan polimorfisme dan casting. Program ini menciptakan dua objek (baris 5-6), lingkaran dan persegi panjang, dan memanggil metode displayObject untuk menampilkannya (baris 9-10). Metode displayObject menampilkan area dan diameter jika objeknya adalah a lingkaran (garis 15), dan area jika 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 lingkaran adalah 3.141592653589793
Diameter lingkaran adalah 2.0
Area persegi panjang adalah 1.0

Metode displayObject (Object object) adalah contoh pemrograman generik. Saya t dapat dipanggil dengan melewatkan instance Objek.
 Program ini menggunakan casting implisit untuk menetapkan objek Circle ke object1 dan a Rectangle object ke object2 (baris 5-6), lalu memanggil metode displayObject untuk ditampilkan informasi tentang benda-benda ini (baris 9-10). 
Dalam metode displayObject (baris 14-25), casting eksplisit digunakan untuk mentransmisikan objek Lingkari jika objek itu adalah instance dari Circle, dan metode getArea dan getDiameter digunakan untuk menampilkan area dan diameter lingkaran. 
Pengecoran hanya bisa dilakukan bila objek sumber adalah turunan dari kelas target. Program menggunakan instanceof operator untuk memastikan bahwa objek sumber adalah turunan dari target kelas sebelum melakukan pengecoran (baris 15). 
Tembakan eksplisit ke Lingkaran (baris 17, 19) dan Persegi Panjang (baris 23) diperlukan karena Metode getArea dan getDiameter tidak tersedia di kelas Object.

Objeknya Sama dengan Metode

Metode lain yang didefinisikan dalam kelas Object yang sering digunakan adalah metode yang sama. Nya tanda tangan adalah
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 memeriksa apakah dua variabel referensi menunjuk ke objek yang sama dengan yang digunakan operator == Anda harus mengganti metode ini di kelas khusus Anda untuk menguji apakah ada dua perbedaan benda memiliki konten yang sama 
Anda telah menggunakan 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 lingkaran 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 berguna untuk menyimpan objek. Anda bisa membuat array untuk menyimpan benda Tapi, begitu array dibuat, ukurannya tetap. Java menyediakan ArrayList kelas yang bisa digunakan untuk menyimpan jumlah objek yang tidak terbatas. Gambar 9 menunjukkan 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 menggunakan konstruktor no-arg (baris 4).
Metode menambahkan menambahkan instance Object ke dalam daftar.
Karena String adalah subkelas dari Object, string bisa ditambahkan ke daftar
Metode menambahkan (baris 7-17) menambahkan objek ke akhir daftar.
Jadi, setelah 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 saat ini 6.
Invoking berisi ("Miami") (baris 22) memeriksa apakah objek ada dalam
daftar. Dalam kasus ini, ia kembali Benar, karena 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) memeriksa apakah daftar
itu kosong Ini mengembalikan false, karena 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 adalah unsur-unsur dalam daftar. Metode get (index) (baris 45)
mengembalikan objek pada indeks yang ditentukan.
Objek ArrayList bisa digunakan seperti array, tapi ada banyak
perbedaan. Tabel 11.1 daftar kesamaan dan perbedaan mereka
Begitu sebuah array dibuat, ukurannya tetap. Anda dapat mengakses
elemen array dengan menggunakan notasi kuadrat-persegi (misalnya,
sebuah [indeks]). Saat ArrayList dibuat, ukurannya adalah 0. Anda tidak
bisa menggunakan metode get dan set jika elemen tidak ada dalam daftar.
Mudah untuk menambahkan, menyisipkan,


dan hapus elemen dalam daftar, tapi agak rumit untuk menambahkan, menyisipkan, dan menghapus elemen sebuah array Anda harus menulis kode untuk memanipulasi array agar bisa melakukan 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 menggunakan ArrayList untuk diimplementasikan Stack, seperti 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 dibuat 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 bagian atas tumpukan tanpa menghapusnya Akhir daftar adalah bagian 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 memeriksa 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.



EmoticonEmoticon