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 }
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