Anda di halaman 1dari 44

Tugas 3

Pemrograman Berorientasi Objek

Oleh :
Gede Thadeo Angga Kusuma (1315051003)
Dhyana Yurs Febrinto

(1315051064)

Luh Putu Diah Utami Chandra Sari (1315051097)


Ella Silviasasmi (1315051077)

JURUSAN PENDIDIKAN TEKNIK INFORMATIKA


FAKULTAS TEKNIK DAN KEJURUAN
UNIVERSITAS PENDIDIKAN GANESHA
SINGARAJA
2016

Bab 2 (Basic Object-Oriented Concepts)

2.1 Implementasi Class


Pada bagian ini kita akan belajar bagaimana mengimplementasikan sebuah class menjadi
sebuah object. Sebagai contoh class kita gunakan class anak sepert berikut :
public class Anak {
private string nama;
public void setNama(string newNama ){
this.nama = newNama;
}
public string getNama(){
return nama;
}
}

Class anak memiliki sebuah attribut nama dengan type string dan memilik access
modifier private, karenanya dibutuhkan sebuah public method untuk memanggil attribut private
yang dikenal dengan GETTER dan SETTER methode. Void setName(string newNama)
merupakan sebuah method untuk memberikan attribute nama sebuah nilai baru yang sudah kita
masukkan pada parameter newNama, namun method ini tidak mengembalikan nilai karena
terdapat Void di depannya.String getNama() tidak memiliki parameter namun memiliki return
berupa attribut nama. Jadi keismpulannya method GETTER diawali dengan Void tidak
memberikan return value namun SETTER diawali dengan tipe data yang ingin dikembalikan,
seperti contoh diatas kita ingin mengembalikan attribut nama dengan tipe string maka diawal kita
sebutkan tipe datanya diikuti dengan nama method dan return nama.

Dari class di atas kita akan implementasikan menjadi sebuah object dan coba memanggil
method atau fungsi dari object yang telah kita buat. Buat sebuah class Anak dengan nama
Tangkas.
Nama Object
Anaka Tangkas = new Anak();
Class ReferenceInstantiates a new object
Maka kita akan memiliki sebuah object dengan nama Tangkas. Setelah object dibuat kita
akan mencoba untuk mengakses method yang dimilikinya pada contoh di atas class Anak
memiliki dua method yaitu getNama() dan setNama(). Cara memanggil method dari sebuh object
yaitu <nama_object><titik = .><nama_method>
Tangkas.setNama(Tangkas);
Untuk lebih memperjelasnya kita akan membuat beberapa object dari
class Anak dan memanggil method yang dimilikinya.
Anaka anak1 = new Anak();
Anaka anak2 = new Anak();
anak1.setNama(Thadeo);
public
class Anak {
anak2.setNama(Wisnu);
private string nama;
System.out.println(anak1.getName());
private int umur;
System.out.println(anak2.getName());
Maka outputnya :
public Anak(string namaAnak) {
this.nama = namaAnak;
}
Thadeo
public void setNama(string newNama ){
Wisnu
this.nama = newNama;
2.2 Constructor
}
Constructor merupakan sebuah method yang dipanggil saat object dibuat atau untuk
public string getNama(){
menginisialisasikan nilai saat object dibuat. Dalam penulisan constructor nama method harus
return
memiliki nama yang
samanama;
dengan class, kita akan membuat sebuah constructor dari class Anak
} kita buat di atas.
yang sudah
public void setUmur(string newUmur ){
this.umur
= newUmur;
public Anak(string
namaAnak)
{
}this.nama = namaAnak;
} Kita akan tambahkan constructor di atas pada class Anak dengan beberapa tambahan.
public string getUmur(){
return umur;
}

\
Kemudian kita akan coba membuat sebuah object dari class Anak yang sudah
dimodifikasi
public classdengan
Anak {menggunakan constructor.
private
string=
nama;
Anak
anak1
new Anak("Thadeo");
private int umur;

Jadi dapat dilihat di pada kode di atas kita membuat object dengan menginisialisasikan
public Anak(){} // Constructor jika tak ada parameter

nama Thadeo secara langsung pada saat pembuatan object. Sekarang coba lihat pada class Anak
public Anak(string namaAnak) {

diatas juga memiliki


attribut umur dan kita juga ingin memberikan nilai umur pada saat
this.nama = namaAnak;
} //Constroctur
dengan
satumembuat
paramtersebuah constructor tambahan dengan parameter
pembuatan
object? Caranya
adalah
public Anak(string
namaAnak,
intmemiliki
newUmur)
{ dari satu constructor sesui kebutuhan
yang di inginkan,
pada sebuah
class dapat
lebih
this.nama = namaAnak;

hal ini dikenal dengan polymorphism yang akan kita bahas pada bab selanjutnya. Kita akan
this.umur = newUmur;

modifikasi
kembali dan menambahkan dua lagi constructor.
} //Constroctur dengan dua paramter
public void setNama(string newNama ){
this.nama = newNama;}
public string getNama(){
return nama;}
public void setUmur(string newUmur ){
this.umur = newUmur;}
public string getUmur(){
return umur;}
}

Contoh pengguna constructor sebagai berikut


Anaka anak1 = new Anak();//Constructor tanpa parameter
Anaka anak2 = new Anak(Thadeo); //Constructor dengan 1 parameter
Anaka anak3 = new Anak(Thadeo,21); //Constructor dengan 2 parameter
2.3 Static Member
Static member merupakan attribut dan method yang dimiliki satu instance dan dimiliki
oleh semua class dan pemanggilannya tanpa harus membuat object terlebih dahulu. Kita
analogikan pada class Anak, pada class ini kita ingin menambahkan satu attribut yang dimiliki
untuk setiap object sama contohnya umur_Imunisasi. Nantinya setiap object yang dibuat akan
memiliki umur_imunisasi yang sama walaupun nanti di ubah, sema object akan tetap memiliki
umurImunisasi yang sama. Jadi kesimpulannya static member yaitu satu nilai atau value untuk
semua

object.

Menggunakan

static

member

dapat

dilakukan

dengan

sintaks

<class_reference>.<member_name>.
Kita akan tambahkan static member pada class Anak dengan type data int dan nama
umur_imunisais.
private static int umurImunisasi;
Dengan static member dan access modifier private kita perlu membuat sebuah setter dan
getter method untuk memanggil dan memberikan nilai pada attribut umur_Imunisasi.
public static void setUmurImunisasi(int newUmurImunisasi) {
this.umurImunisasi = newUmurImunisasi;
}
public static int UmurImunisasi () {
return umurImunisasi;
}

Contoh penggunaan static method yang ditambahkan pada class Anak.


Anak anak1 = new Anak("Wisnu");
anak1.setUmurImunisasi(6);
Karena static method yang kita buat bersifat private dan untuk pemberian nilai harus
melalui object dan jika ingin secara langsung mengubah nilai static member kita bisa ganti
private mejadi public papda class dan jadinya akan seperti berikut
Public static int umurImunisasi;
Dan cara pemanggilannya menjadi:
Anak.umurImunisasi = 6;

2.4 Program Dengan Multiple Class


Memprogram dengan multiple class atau lebihb dari satu class artinya menggunakan
sebuah class pada class yang lain. Misalnya class A kita panggil atau gunakan pada implementasi
class B. Kita akan menggunakan kembali class Anak yang sudah dibuat sebelumnya dan
digunakan pada class OrangTua yang selanjutnya akan kita buat. Berikut contoh sederhana
penggunaan mutiple class.
Class Anak :
public class Anak {
public class
private
OrangTua
string nama;
{
private string
namaOrtu;
int umur;

2.5 Asdas
private
public Anak(){}
Anak anak; // Penggunaan Multiple class
2.6 Dasdas
public OrangTua(){}
Anak(string namaAnak) {this.nama = namaAnak; }
2.7
public OrangTua
Anak(string
(string
namaAnak,
newNama,
int newUmur)
Anak newAnak)
{
{
this.namaOrtu
= newNama;
this.nama = namaAnak;
this.anak
this.umur =
= newAnak;
newUmur;
}
public void setNamaOrtu(string
setNama(string newNama
newNama
){this.nama
){
= newNama;}
this.namaOrtu
= newNama;}
public string
getNama(){return
nama;}
public string
void setUmur(string
getNamaOrtu(){
newUmur ){this.umur = newUmur;}

Class OrangTua;
returngetUmur(){return
namaOrtu;}
public string
umur;}
}

public void setAnak(Anak newAnak){


this.anak = newAnak;}
public Anak getAnak(){
return anak;}

Pada class OrangTua bisa kita liat penggunaan class Anak pada class OrangTua dan juga
dimasukkan pada parameter constructor sebagai inisialisasi saat pembuatan object class
OrangTua. Berikut contoh penggunaan class diatas dalam pembuatan object.
Anak anak1 = new Anak(Tangkas,20);
OrangTua orangTua1 = new OrangTua(Ari Satria, anak1);

Pada sintak di atas bisa dilihat object anak1 di parsing pada constructor object orangTua1
sehingga menginisialisasikan nilai attribut anak pada orang tua dengan object anak1.

2.5 Interface
Interface merupakan sebuah class yang berisi deklarasi method abstract yang tidak ditulis
secara utuh atau lengkap. Deklarasi method pada interface mirip dengan method pada class
abstract. Variable pada interface bersifat static dan final sedangkan method bersifat public dan

abstract. Interface dapat digunalan dengan keyword Implements setelah nama class yang artinya
class yang mengimplement sebuah interface harus melengkapi seluruh method yang ada pada
interface tersebut. Contohnya disini kita akan membuat sebuah interface dengan nama
DaftarAnak dan memiliki beberapa method diantaranta tambah(), hapus(), dan tampil().
public interface DaftarAnak {
public void tambah(AnaknewAnak);
public void hapus(string name);
public void tampil();
}

Setelah kita membuat sebuah interface dengan nama Daftar Anak, kita akan
menggunakan interface tersebut pada class kita sehinga class kita harus menggunakan seluruh
method yang sudah di deklarasikan pada interface, kita kan membuat sebeuah class dengan nama
AnakSD2 dengan implementasi interface DaftarAnak sebagai berikut:
public class AnakSD2implements DaftarAnak{
public void tambah(AnaknewAnak){ sintak tambah }
public void hapus(string name){ sintak hapus }
public void tampil(){ sintak tampil }
//metod yang lainnya
}

Seperti sintak di atas seluruh method pada interface harus di implementasikan atau
dilengkapi jika tidak program akan mengembalikan error. Sebuah class dapae mengimplementasi
lebih dari satu interface contohnya :
public class AnakSD2implements DaftarAnak, DaftarOrangTua{}
2.6 Abstract Class

Class abstract digunakan untuk mendefinisikan sebuah class yang hanya mendeklarasikan
sebagian atau belum lengkap tanpa mengimplementasikan secara detail fungsi-fungsi dari kelas
abstrak yang ada. Penggunaan class abstract menggunakan keyword extends seperti class-class
yang lainnya berbeda dengan interface yang menggunakan keyword implements. Perintah
abstract diletakkan sebelum nama Class dan nama Method. Semua abstract method yang ada
dalam abstract class wajib diimplementasi/dilengkapi oleh semua class turunan (sub class) yang
bukan abstract.Berikut contoh pembuatan class abstract:
public abstract class DaftarAnak {
public abstract void tambah();
public abstract void hapus();
public abstract void tampil();
}

Selanjutnya kita buat implementasi atau cara penggunaan abstract class DaftarAnak.
public class AnakSD2extends DaftarAnak{
public void tambah(AnaknewAnak){ sintak tambah }
public void hapus(string name){ sintak hapus }
public void tampil(){ sintak tampil }
//metod yang lainnya
}
Class AnakSD2 merupakan turunan yang mengextends method abstract dari class abstract
DaftarAnaka. Class abstract tidak bisa dibuat menjadi sebuah object, hanya class yang semua
methodnya sudah diimplementasikan dan dilengkapi dapat di buat sebuah object. Berikut contoh
penggunaannya:
public class Test {
public static void main(String[] args) {
AnakSD2 daftar = new AnakSD2();
daftar.tambah();
daftar.tampil();
}
}

2.7 Membandingkan Object


Membandingkan 2 buah object biasanya digunakan equal method mebandingkan dua
buah variabel akan lebih mudah, namun jika membandingkan dua buah object akan menjadi
sedikit lebih rumit. Jadi untuk membandingkan dua buah object kita harus membuat sebuah
special method, sebagai contoh kita akan membandingkan dua buah object dari class Anak
sebagai berikut :
public boolean equals (Object anObject) {

Anakanak = (Anak) anObject;


return anak.nama.equals(nama) && anak.umur.equals(umur);
}

Method diatas di tambahkan di dalam class Anak, setelah ditambahkan berikut contoh
penggunaannya.
Anak anak1 = new Anak("Angga",12);
Anak anak2 = new Anak("Angga",12);
if (anak1.equals(anak2)) {
System.out.println("anak1 sama dengananak2");
} else {
System.out.println("anak1 berbeda dengananak2");
}

2.8 Notation for Describing Object-Oriented Systems


Mendokumentasikan sebuah sistem atau program sangatlah penting. Dalam kegiatan
dokumentasi Object Oriented System biasanya digunakan UML atau Unified Modeling
Language.UML (Unified Modelling Language) sendiri adalah sebuah bahasa yang menjadi
standar dalam industri untuk visualisasi, merancang dan mendokumentasikan sistematau
program.UML mendefinisikan notasi dan syntax/semantik. Notasi UML merupakan sekumpulan

bentuk khusus untuk menggambarkan berbagai diagram program. UML diagram dapat dibagi
menjadi 3 bagian yaitu
1 Structure Diagrammenunjukkan arsitektur statis dari sistem terlepas dariwaktu.
2 Behaviour Diagram yang menggambarkan perilaku sistem atau proses bisnis.
3 InteractionDiagram yang menunjukkan metode, interaksi dan kegiatan dari obyek.
Strukture diagram terbagi menjadi beberapa bagian diantaranya :
1 Class diagram
Digaram yang memperlihatkan class, attribut, method dan relasi tiap class
2 Composite strukture diagram
Diagram yang menunjukan struktur internal classifier, termasuk poin interaksinya ke
3
4

bagian lain dari sistem.


Component diagram
Diagram ini memperlihatkan detail dari sebuah komponen.
Deployment diagram

Diagram yang menggambarkan penugasan executable file pada komponen komputer.


Object diagram
Object diagram merupakan sebuah gambaran tentang objek-objek dalam sebuah sistem

pada suatu waktu.


Package diagram
Diagram yang mengelompokkan class kedalam sebuah paket dan paket dapat dimasukkan
ke paket yang berbeda.

Gambar 1. Tipe Structure Diagram


Behaviour diagram terbagi menjadi beberapa bagian diantaranya:
1. Activity diagram

Diagram ini mirip dengan flowchart yang menyediakan analis dengan kemampuan untuk
memodelkan proses dalam suatu sistem informasi
2. Use case diagram
Diagram ini bekerja dengan cara mendeskripsikan tipe interaksi antara user sebuah sistem
dengan sistemnya sendiri melalui sebuah alurpenggunaan sistem.
3. State machine diagram
Diagram ini digunakan untuk memodelkan perilaku dinamis satu kelas atau objek selama
masa hidupnya.

Gambar 2. Tipe Behaviour Diagram

Interaction diagram terbagi menjadi beberapa bagian diantaranya:


1. Sequence diagram
Sequence diagram menjelaskan interaksi objek yang disusun berdasarkan urutan waktu.
2. Timing diagram
Timing Diagram adalah bentuk lain dari interaction diagram, dimana focus utamanya
lebih ke waktu.
3. Communication diagram
Communication diagram menggambarkan interaksi antar objek seperti sequence diagram,
tetapi lebih menekankan pada peran masing-masing objek
4. Interaction overview diagram
Diagram yange menampilkan control yang sangat tinggi dan menampilkan interaksi antar
sequance diagram dan communication diagram.

Gambar 3. Tipe Interactio


2.8.1.

diagram

Class diagram
Class

diagram biasanya mengandungattribut-atribut, method, access modifier


dan hubungan tiap class. Sebagai contoh kita membangun sebuah aplikasi penilaian dosen, class
diagram akan berisi classdosen, fakultas, pangkat dan dan relasi atau hubungan tiap classnya jika
ada. Diagram berfungsi untuk menjelaskan tipe dari object sistem dan hubungannya dengan
object yang lain. Simbol menandakan private access, + menandakan public access dan #
menandakan protected access. Berikut contoh class diagram :

Gambar 4. Class Diagram


2.8.2.

Use CaseDiagram

Usecase diagram adalah diagram usecase yang digunakan untuk menggambarkan secara
ringkas siapa yang menggunakan sistem dan apa saja yang bisa dilakukannya. Diagram
usecase tidak menjelaskan secara detail tentang penggunaanusecase, namun hanya memberi
gambaran singkat hubungan antara usecase, aktor, dan sistem.

Gambar 5. Contoh use case mesin ATM

2.8.3.
SequenceDiagram
Sequence diagram adalah suatu diagram yang menggambarkan interaksi antar obyek dan
mengindikasikan komunikasi diantara obyek-obyek tersebut. Diagram ini juga menunjukkan
serangkaian pesan yang dipertukarkan oleh obyek obyek yang melakukan suatu tugas atau
aksi tertentu

Gambar 6.

Contoh sequence diagram

BAB 3 (Relationships between Classes)


3. Hubungan antara Kelas
Dalam rangka untuk membangun sistem perangkat lunak, kita perlu mekanisme yang
menciptakan hubungan antara bangunan blok. Dalam bab ini kita memperkenalkan tipe dasar
hubungan antara kelas (benda) yang membuat koneksi.
Jenis yang paling sederhana dan paling umum dari hubungan adalah asosiasi, yang
hanya menunjukkan bahwa objek dari dua kelas yang terkait dalam beberapa cara nonhirarkis.
Jenis kedua, ketika dua atau lebih kelas memiliki hubungan hirarkis berdasarkan
generalisasi, itu disebut sebagai warisan. Kelas terhubung oleh warisan terbagi beberapa
kesamaan dan karena itu, hubungan semacam ini lebih terbatas daripada asosiasi.
Jenis yang ketiga dari hubungan yang kita lihat adalah genericity. Ini lebih rumit
daripada warisan karena fakta bahwa satu-satunya variasi diizinkan di kelas terkait adalah
mereka yang dapat ditangkap oleh jenis parameter, yaitu, memberikan parameter dari jenis
yang berbeda saat membuat sebuah instance dari entitas generik.
Untuk itu dari ketiga jenis hubungan antara lain asosiasi, warisan, dan genericity dapat
kita bahas sebagai berikut:
3.1 Asosiasi
Asosiasi secara resmi didefinisikan sebagai hubungan antara dua atau lebih kelas
menggambarkan sekelompok link dengan struktur umum dan semantik. Sebuah asosiasi
menyiratkan bahwa obyek dari satu kelas yang memanfaatkan sebuah objek dari kelas
lain dan ditandai hanya dengan garis yang solid yang menghubungkan dua ikon kelas.

Kuliah
Mendaftar
untuk
Mahasiswa
Gambar
3.1 Hubungan
antar kelas
Sebuah asosiasi tidak berarti bahwa selalu ada hubungan antara semua benda dari
satu kelas dan semua benda yang lain. Sebagai salah satu harapkan, dalam contoh kita,
link terbentuk antara objek Mahasiswa dan objek Kuliah hanya ketika operasi yang
menghubungkan mereka selesai, yaitu, mahasiswa diwakili oleh register objek
Mahasiswa untuk itu program tertentu. Namun, sebuah asosiasi yang menyiratkan bahwa
ada persisten, koneksi diidentifikasi antara dua kelas. Jika kelas A dikaitkan dengan kelas
B, berarti diberikan sebuah objek dari kelas A, Anda selalu dapat menemukan sebuah
objek dari kelas B, atau Anda dapat menemukan bahwa tidak ada objek B telah

ditetapkan asosiasi sebelumnya. Tapi dalam kedua kasus selalu ada jalan diidentifikasi
dari A ke B. Asosiasi demikian mewakili hubungan konseptual antara kelas serta
hubungan fisik antara objek-objek dari kelas-kelas.
Dalam hal pelaksanaan, apa yang dikatakan di atas menyiratkan bahwa kelas A harus
menyediakan mekanisme menggunakan konstruksi bahasa pemrograman yang dipilih
untuk membentuk link. Ini bisa mengambil beberapa bentuk, misalnya,
Kelas A menyimpan kunci (atau beberapa kunci) yang secara unik

mengidentifikasi objek dari kelas B.


Kelas A menyimpan referensi (s) ke objek (s) dari kelas B.
Kelas A memiliki referensi ke sebuah objek dari kelas C, yang, pada gilirannya

berhubungan dengan contoh yang unik dari kelas B.


Pertama dan kedua ini membuat hubungan langsung, sedangkan yang ketiga adalah
sebuah asosiasi tidak langsung. Mekanisme yang dipilih tergantung pada persyaratan
bahwa sistem harus memenuhi (misalnya, jenis pertanyaan yang perlu dijawab) dan juga
pada bagaimana sisa sistem dirancang (lihat Gambar 3.2).
*

Mahasiswa Mendaftar di

Bagian

1
Milik

Kuliah

Gambar 3.2 Asosiasi yang melibatkan tiga kelas


Entitas di akhir asosiasi biasanya sudah ditetapkan tugasnya, yang mungkin
memiliki nama. Kita bisa memiliki asosiasi bernama 'mempekerjakan' yang
menghubungkan kelas yang mewakili Bisnis untuk kelas yang mewakili Orang yang
dipekerjakan oleh bisnis. Berikut Bisnis memainkan peran dari majikan dan Orang
memiliki peran karyawan.
3.1.1 Karakteristik asosiasi
Ketika asosiasi merupakan hubungan yang sangat umum, mereka
memungkinkan untuk variasi dalam sifat koneksi. Variasi umum adalah arity
dari koneksi, yaitu, berapa banyak benda dari kelas A dapat dihubungkan ke
salah satu objek dari kelas B dan sebaliknya. Variasi lain melibatkan apakah
ada beberapa bentuk penahanan yang terlibat dalam hubungan. Dalam kasus
lain ada beberapa jenis tertentu informasi yang ditambahkan ke sistem setiap
kali link dibuat antara objek. Karakteristik ini biasanya direpresentasikan

dalam UML oleh annotating hubungan antara kelas. Beberapa ini dibahas di
bawah.
Hubungan Arity
Hubungan arity bisa menjadi satu-satu, satu-banyak, atau banyak-banyak.
Sebuah sistem multi user, bagaimanapun, dapat berinteraksi dengan beberapa
pengguna secara paralel.
Hubungan Penahanan
Agregasi adalah semacam asosiasi di mana objek dari kelas A 'terdiri dari'
objek kelas B. Hal ini menunjukkan beberapa jenis hubungan keseluruhanbagian antara A dan B. Komposisi menyiratkan bahwa setiap contoh dari
bagian milik hanya satu contoh dari keseluruhan, dan bahwa bagian itu tidak
bisa eksis kecuali sebagai bagian dari keseluruhan. Pada Gambar 3.3, tinggi
tidak bisa eksis kecuali itu adalah bagian dari segitiga.

Segi Gambar
Tiga 3.3 Komposisi diTinggi
kelas

Kelas Asosiasi
Sebuah asosiasi biasanya menghasilkan beberapa informasi yang
ditambahkan ke sistem karena menambahkan jalan yang menghubungkan dua
benda. Dalam beberapa situasi kita menambahkan beberapa informasi yang
memenuhi syarat alam dan menggambarkan sifat hubungan. Di luar konteks
asosiasi, informasi ini tidak memiliki relevansi dengan salah satu benda yang
terlibat. Dalam kasus seperti kita memperlakukan asosiasi itu sendiri sebagai
sebuah kelas. Contoh ini ditunjukkan pada Gambar 3.4. Ketika seorang
mahasiswa mendaftar di petugas pendaftaran, maka catatan pendaftaran dibuat
untuk menyimpan tanggal pendaftaran dan kelas. rekaman seperti itu tidak
masuk akal jika seorang mahasiswa tertentu tidak mendaftar di petugas
* mendaftar di*
Petugas pendaftaran
Mahasiswa
pendaftaran yang ditetapkan.

Pendaftaran
+ tanggal : date
+ Kelas : Char =12

Gambar 3.4 Menggunakan kelas asosiasi

3.2 Warisan
Warisan dapat didefinisikan sebagai mekanisme yang disediakan dalam bahasa
pemrograman untuk mencapai gagasan generalisasi vertikal. Secara formal, warisan
adalah hubungan ditandai dengan nenek moyang dan keturunan yang di wakili
menggunakan notasi UML seperti pada Gambar 3.5. Di sini, baseclass adalah leluhur dan
Derived class adalah keturunan. Kami mengambil satu kotak per kelas dan menarik garis
panah dari Derived class ke Baseclass.
Base Class
Common attributes
+ Common methods ()

Derived classGambar
1
3.5 Ide dasar dariDerived
warisan class 2
attributes unique to this class

attributes unique to this class

+ method unique to this class ()

+ method unique to this class ()

3.2.1

Contoh Hirarki
Dalam java dapat dilakukan sebagai berikut. Pertama membuat kelas yang

menangkap sifat-sifat penting dan method umum untuk semua produk (Televisi
dan Buku).
public class Product {
// fungsionalitas untuk produk
}

Sekarang untuk membuat kelas yang mewakili satu set TV. Untuk mencatat
bahwa televisi merupakan produk dan fungsi yang hanya dilaksanakan untuk
produk. Di Java, dapat menuliskan coding sebagai berikut:
public class Television extends Product {
// fungsi yang unik untuk televisi
// modifikasi
}
Informasi yang didapatkan dari kelas Televisi adalah mewarisi semua
properti dan method dari kelas Product. Semua yang dilakukan adalah
menambahkan properti dan method unik untuk televise. Dengan cara yang sama,
untuk menuliskan coding kelas Book sebagai berikut:
public class Book extends Product {
// fungsi yang unik untuk buku
// modifikasi
}
Hubungan antara tiga kelas digambarkan pada Gambar 3.6
Product

Television
Gambar 3.6 Inheriting fromBook
product

Struktur kelas
Dalam bagian ini menjelaskan bagaimana cara kerja hubungan warisan.
Fungsionalitas yang diperlukan dari dua kelas television dan Book, diberikan pada
Gambar 3.7.
Sekarang, perhatikan persamaan dan perbedaan antara dua kelas. Mereka
mewakili produk, membawa kuantitas bidang penjualan dan harga dengan makna
Television

Book

yang jelas. Method sale () di kedua kelas dipanggil kapan satu unit (buku atau satu
model : string

title : string

manufacture : string

price : double

set
TV): double
dijual. Arti dari method setPrice () harus
price
authorjelas.
: string
quantitySold : int

publisher : string
quaintySold : int
+ Television (manufacture : string), model : string
+ Book (title:string, author:string, publisher:string)
+ sale () : void
+ sale () : void
+ setPrice (newPrice : double) : void
+ setPrice (newPrice:double) : void

Gambar 3.7 Contoh kelas yang sama


Dua kelas yang agak berbeda dalam hal lain: Book memiliki atribut title
(judul) dan outhor (penulis), sedangkan kelas Television memiliki atribut brand
(merek). Atribut produsen bernama berbeda, namun tidak berbeda dengan,
publisher (penerbit).
Diagram UML yang menunjukkan pengaturan ditunjukkan pada Gambar 3.8.
Produk kelas melacak atribut umum Book dan Television dan menerapkan method
yang diperlukan untuk bertindak atas atribut ini. Television dan Book sekarang
dibangun sebagai subclass dari produk, sehingga mereka berdua akan mewarisi
fungsi dari produk, dan mereka sekarang mampu melacak penjualan kedua produk
ini.
Coding untuk produk ditunjukkan di bawah ini, cukup sederhana. Perusahaan
variabel menyimpan produsen produk. Jika tidak, tidak ada fitur khusus yang akan
dibahas.
public class Product {
private String company;
private double price;
private int quantitySold;
public Product(String company, double price) {
this.company = company;
this.price = price;
}
public void sell() {
quantitySold++;
}
public void setPrice(double newPrice) {
price = newPrice;
}
public String toString() {
return "Company: " + company + " price: " +
price + " quantity sold " + quantitySold;

}
}

Product
price : double
company : string
quantitySold : int
+ product (company:string)
+ sale () : void
+ setPrice (newPrice:double):void

Gambar 3.8 Mewarisi dari produk


Television

Book

Ingat bahwa objek dijalankan melalui kode di konstruktor. Ketika warisan

model : string

title : string

yang terlibat, bagian dari objek yang diwakili


oleh: superclass
harus diinisialisasi
author
string

+ Television (manufacturer:string, model:string)

+ Television
(manufacturer:string,
sebelum bidang subclass diberikan nilai. Sebuah
analogi
dapat membantu,model:string)
ketika

rumah dibangun, atap diletakkan hanya setelah dinding sudah didirikan, yang
terjadi hanya setelah pondasi telah diletakkan.
Untuk membuat objek televisi, kita memanggil konstruktor dari kelas yang
seperti di bawah ini, di mana kita mengirim nama merek, nama produsen, dan
harga.
Television set = new Television("RX3032", "Modern Electronics", 230.0);
Sehingga konstruktor dari televisi harus didefinisikan sebagai berikut.
public Television(String model, String manufacturer, double price) {
// Kode untuk menginisialisasi bagian Produk dari televisi
// Kode untuk menginisialisasi bagian televisi objek
}
Kita sudah memiliki sepotong kode yang initialises bidang objek Produk:
konstruktor dari Produk. Jadi semua yang perlu kita lakukan adalah memanggil
konstruktor itu! Hal ini dilakukan dengan pernyataan Panggilan super dengan
parameter yang tepat selalu memanggil konstruktor superclass ini. Superclass
'panggilan konstruktor dapat dipanggil hanya sebagai pernyataan pertama dari

kode tersebut dalam constructor dari subclass; tidak dapat ditempatkan setelah
beberapa kode atau ditempatkan dalam method.
Dalam contoh ini, parameter yang akan dilalui akan nama produsen dan
harga. Kode untuk constructor kemudian
public Television(String model, String manufacturer, double price) {
super(manufacturer, price);
// Menyimpan nama model
}
Bidang superclass yang dijalankan kedepan bidang dalam subclass. Apa ini
berarti dalam konteks pembuatan obyek adalah bahwa konstruktor dari televisi
dapat mulai bekerja hanya setelah constructor dari superclass eksekusi produk
telah selesai. Tentu saja ketika Anda ingin membuat objek televisi Anda perlu
untuk memanggil konstruktor kelas, tetapi hal pertama yang constructor Televisi
tidak dan harus dilakukan adalah memanggil konstruktor dari Produk dengan
parameter yang sesuai nama perusahaan yang memproduksi set dan harga.
Seperti yang diharapkan, kelas televisi kebutuhan lapangan untuk
menyimpan nama model. Dengan demikian kita memiliki setengah lebih lengkap
coding untuk kelas ini, seperti contoh di bawah ini.
public class Television extends Product {
private String model;
public Television(String model, String manufacturer, double price) {
super(manufacturer, price);
this.model = model;
}
public String toString() {
return super.toString() + " model: " + model;
}
}
Untuk String() method Televisi bekerja dengan terlebih dahulu memanggil
untuk String () method Produk, yang mengembalikan representasi string dari
Produk dan merangkai untuk nama model.
3.2.2

Mewarisi dari sebuah antarmuka


Jeis khusus warisan adalah salah satu di mana kelas mewarisi dari sebuah
antarmuka. Java mengakui sebuah antarmuka sebagai jenis (seperti yang

dilakukan beberapa bahasa berorientasi objek lainnya), yang berarti bahwa bendabenda yang termasuk kelas yang mengimplementasikan antarmuka yang diberikan
juga termasuk ke dalam jenis yang diwakili oleh antarmuka. Demikian juga, kita
bisa mendeklarasikan identifier sebagai milik jenis antarmuka dan kita kemudian
dapat menggunakannya untuk mengakses objek dari setiap kelas yang
mengimplementasikan antarmuka.
public interface I {
// rincian dari I
}
public class A implements I {
//code untuk A
}
public class B implements I {
//code untuk B
}
I i1 = new A(); // i1 memegang A
I i2 = new B(); // i2 memegang B
Dalam notasi UML, jenis hubungan antara interface dan kelas yang
mengimplementasikan disebut realisasi dan diwakili oleh garis putus-putus
dengan panah terbuka besar yang menunjuk ke antarmuka seperti yang
ditunjukkan pada Gambar 3.8.
3.2.3

Polimorfisme dan dinamis mengikat


Mempertimbangkan aplikasi universitas yang berisi antara lain, tiga kelas
yang membentuk hierarki seperti yang ditunjukkan pada Gambar 3.9. Seorang
siswa dapat berupa seorang mahasiswa sarjana atau mahasiswa pascasarjana.
Sama seperti dalam kehidupan nyata di mana kita akan berpikir sarjana atau
mahasiswa pascasarjana sebagai mahasiswa, dalam paradigma berorientasi objek
juga, kita mempertimbangkan suatu objek Undegradeate atau Graduate Student
menjadi tipe Student. Oleh karena itu, kita dapat menulis
Student student1 = new UndergraduateStudent();
Student student2 = new GraduateStudent();
Student
Name : string
qpa : double
+ isInGoodStanding () : Boolean
+ getGPACutoff () : double

UndergraduateStudent

GraduateStudent

Gambar 3.9 Hirarki mahasiswa


Ini adalah ide yang kuat. Kita sekarang dapat menulis method yang menerima
mahasiswa dan lulus baik sebagai mahasiswa sarjana atau benda Graduate Student
untuk itu seperti di bawah ini.
public void storeStudent(Student student) {
// kode untuk menyimpan objek Mahasiswa
}
Kami dapat membuat Sarjana Mahasiswa dan Mahasiswa Pascasarjana objek
dan meneruskannya ke method di atas
storeStudent(new UndergraduateStudent());
storeStudent(new GraduateStudent());
Sekali lagi, dalam kehidupan nyata, kita biasanya tidak berpikir dari seorang
mahasiswa pascasarjana sebagai mahasiswa sarjana atau sebaliknya. Dengan cara
yang sama, kita tidak bisa menulis kode berikut di Java
UndergraduateStudent student1 = new GraduateStudent(); // salah
GraduateStudent student2 = new UndergraduateStudent(); // salah
.
Karena kita membiarkan referensi Mahasiswa untuk menunjuk ke kedua
UndergraduateStudent dan GraduateStudent objek, kita dapat melihat bahwa
beberapa, tapi tidak semua referensi Mahasiswa dapat menunjuk ke objek dari
jenis UndergraduateStudent; sama, beberapa referensi Mahasiswa bisa merujuk ke
objek tipe GraduateStudent. Dengan demikian, kita tidak bisa menulis,
Student student1;
student1 = new UndergraduateStudent();
GraduateStudent student2 = student1; // wrong!
Compiler akan menandakan bahwa kode tidak benar.
Tapi, kode berikut, intuitif yang benar, ditandai oleh compiler sebagai salah.
Student student1;

student1 = new GraduateStudent();


GraduateStudent student2 = student1; // compiler menghasilkan kesalahan
sintaks.
Alasan untuk kesalahan ini adalah bahwa compiler tidak mengeksekusi kode
untuk menyadari bahwa Murid1 sebenarnya mengacu pada sebuah objek dari tipe
GraduateStudent. Hal ini mencoba untuk melindungi programmer dari situasi
yang absurd yang bisa terjadi jika Murid1 mengadakan referensi ke sebuah obyek
UndergraduateStudent.

Ini

adalah

tanggung

jawab

memberitahu compiler bahwa Murid1 sebenarnya

programmer

untuk

menunjuk ke objek

GraduateStudent. Hal ini dilakukan melalui gips seperti yang ditunjukkan di


bawah ini.
Student student1;
student1 = new GraduateStudent();
GraduateStudent student2 = (GraduateStudent) student1; //O.K. Code bekerja.
Untuk mengulangi, programmer harus memastikan bahwa para pemain akan
bekerja dengan benar; compiler akan dengan senang hati memungkinkan kode
untuk lulus pemeriksaan sintaks, tetapi kode sembarangan ditulis akan crash
ketika dijalankan. Lihat kode berikut.
Student student1;
student1 = new UndergraduateStudent();
GraduateStudent student2 = (GraduateStudent) student1; // crash
Murid1 tidak menunjuk ke objek GraduateStudent di baris terakhir, sehingga
upaya sistem untuk melemparkan contoh UndergraduateStudent ke sebuah contoh
dari GraduateStudent akan gagal dan kode akan crash 1.
Aturan umum adalah sebagai berikut. Lihat Gambar 3.10.
1. Setiap objek dari jenis SubClass1 atau SubClass2 dapat disimpan dalam
referensi jenis superclass.
2. Tidak ada objek bertipe SubClass1 (SubClass2) dapat disimpan dalam
referensi jenis SubClass2 (SubClass1).
3. Sebuah referensi jenis superclass dapat berperan sebagai acuan tipe
SubClass1 atau SubClass2.

Tugas dari jenis di atas disebut polimorfik. Referensi adalah mampu untuk
menunjuk ke objek dari berbagai jenis selama jenis sebenarnya dari benda-benda
sesuai dengan jenis referensi. Peraturan di atas informal memberikan pengertian
tentang kesesuaian.
Ini adalah pelajaran untuk membandingkan tugas dan gips yang diberikan di
atas dengan aturan untuk tugas dan gips variabel dari tipe primitif. Beberapa jenis
konversi, misalnya, dari int untuk fload.
Superclass

Gambar 3.10

Subclass1

Subclass2

Dalam salah satu dari ini, kita menyimpan referensi ke objek dari
GraduateStudent kelas di suatu entitas yang menyatakan jenis adalah mahasiswa.
Ini setara dengan mengambil sekelompok pisang dan menyimpannya dalam kotak
berlabel 'buah'. Isi menyatakan kotak (seperti yang diberikan oleh label) adalah
buah, seperti jenis menyatakan entitas Murid1 di LHS dari tugas adalah
Mahasiswa. Dengan melakukan ini, kita telah kehilangan beberapa informasi
karena kita tidak bisa lagi mencari tahu apa jenis buah yang kita miliki dalam
kotak tanpa memeriksa isinya. Demikian juga, ketika kita beroperasi pada entitas
Murid1, semua kita bisa berasumsi adalah bahwa hal itu berisi referensi ke objek
Mahasiswa. Demikian ada hilangnya informasi dalam jenis tugas.
Jenis kedua tugas polimorfik adalah salah satu di mana kami pindah referensi
dari suatu entitas yang menyatakan jenis adalah Student untuk entitas yang
menyatakan jenis adalah GraduateStudent. (Ini akan berjumlah mengambil pisang
dari kotak berlabel 'buah' dan menempatkan mereka dalam kotak berlabel 'pisang',
kami melakukan ini hanya jika kita yakin bahwa kotak memang memiliki pisang).
Untuk mendapatkan pemahaman yang konkret, mari kita kembali ke contoh
hirarki Mahasiswa. Kode untuk Mahasiswa dapat ditulis sebagai berikut.
public abstract class Student {
private String name;
private double gpa;
// more fields
public Student(String name) {

this.name = name;
}
public String getName() {
return name;
}
public boolean isInGoodStanding() {
return (gpa >= getGPACutoff());
}
public abstract double getGPACutoff();
// more methods
}
Dalam prakteknya, kelas Mahasiswa akan jauh lebih rumit, karena dalam
kode ada yang hilang kerangka utama yang seharusnya ada. Seperti yang Anda
lihat, nama mahasiswa yang akan dijalankan dalam konstruktor. Indeks Prestasi
Kumulatif (IPK) disimpan dalam bidang double gpa. Sebagai siswa

akan

mendapatkan

akan

kelas

dan

menyelesaikan

kuliahnya,

maka

mereka

mendapatkan nilai yang akan digunakan dalam menghitung IPK. Tak satu pun dari
kode yang ditunjukkan di kelas ini.
Kami berasumsi bahwa secara berkala, mungkin pada akhir setiap semester
atau triwulan, universitas akan memeriksa siswa untuk melihat apakah mereka
berada di 'performa yang baik'. Biasanya, itu berarti memastikan bahwa siswa
mengalami kemajuan dalam cara memuaskan. Kami berasumsi bahwa untuk
siswa performa yang baik berarti bahwa IPK siswa memenuhi persyaratan
minimum tertentu. IPK minimal diharapkan siswa dapat berubah tergantung pada
apakah

siswa

adalah

sarjana

atau

mahasiswa

pascasarjana.

Method

getGPACutoff() mengembalikan IPK minimal mahasiswa harus dalam performa


yang baik. Kami akan menganggap bahwa nilai ini adalah 2,0 dan 3,0 untuk
mahasiswa sarjana dan pascasarjana masing-masing. Perhatikan bahwa method ini
menyatakan abstrak di kelas Siswa.
Mari kita fokus pada kode untuk UndergraduateStudent, yang diberikan di
bawah.
public class UndergraduateStudent extends Student {
public UndergraduateStudent(String name) {
super(name);
}
public double getGPACutoff() {

return 2.0;
}
}
konstruktor mendapatkan nama siswa karena hanya parameter dan memanggil
konstruktor superclass untuk menyimpannya. Karena ini adalah kelas non-abstrak,
method getGPACutoff yang mengembalikan minimum IPK diimplementasikan.
Semua method superclass public dan protected yang diwariskan dalam dua
subclass. Jadi, method ini pada GoodStanding dapat dipakai pada sebuah instance
dari UndergraduateStudentas baik. Jadi kode berikut ini berlaku.
UndergraduateStudent student = new UndergraduateStudent("Tom");
// code to manipulate student
if (student.isInGoodStanding()) {
// code
} else {
// code
}
Ketika metode ini dibuat, dalam method GoodStanding di Student
superclass akan dipanggil.
Akhirnya, kita memiliki kode untuk kelas GraduateStudents (mahasiswa
pascasarjana). Konstruktor untuk kelas ini cukup mirip dengan yang untuk kelas
UndergraduateStudent (mahasiswa sarjana). Untuk membuat kelas non-abstrak,
kelas ini juga, harus memiliki implementasi getGPACutoff. Selain itu, kami
menganggap bahwa mahasiswa baik berdiri di pascasarjana harus memenuhi
persyaratan yang dikenakan pada semua siswa dan, di samping itu, mereka tidak
dapat memiliki lebih dari jumlah tertentu kursus di mana mereka mendapatkan
kelas di bawah, mengatakan B.
Apa yang kami suka adalah oroverriding redefinisi method ini dalam
GoodStanding. Utama dilakukan dengan mendefinisikan sebuah method dalam
subclass dengan nama yang sama, jenis return, dan parameter sebagai method
dalam superclass sehingga definisi subclass ini lebih diutamakan daripada method
superclass. Sehingga kode dalam method GoodStanding sekarang berbeda. Lihat
di bawah.
public class GraduateStudent extends Student {
public GraduateStudent(String name) {

super(name);
}
public double getGPACutoff() {
return 3.0;
}
public boolean isInGoodStanding() {
return super.isInGoodStanding() && checkOutCourses();
}
public boolean checkOutCourses() {
// implementation not shown
}
}
Sekarang, misalkan kita memiliki kode berikut.
GraduateStudent student = new GraduateStudent("Dick");
// code to manipulate student
if (student.isInGoodStanding()) {
// code
} else {
// code
}
Dalam hal ini, panggilan untuk GoodStanding adalah hasil dalam panggilan untuk
kode didefinisikan dalam kelas GraduateStudent. Hal ini pada gilirannya
memanggil kode di kelas Mahasiswa dan membuat pemeriksaan lebih lanjut
dengan menggunakan method checkOutCourses dinyatakan secara lokal untuk
sampai pada keputusan.
Ingat kelas StudentArrayList kita definedin Bagian 2.4 yang menyimpan
benda mahasiswa. Method untuk menambahkan Mahasiswa di kelas ini tampak
sebagai berikut:
public void add(Student student) {
// code
}
Sejak referensi Mahasiswa dapat menunjuk ke UndergraduateStudent atau
GraduateStudent, kita dapat melewati objek dari kedua jenis method add dan telah
mereka simpan dalam daftar. Misalnya, kode
StudentArrayList students = new StudentArrayList();
UndergraduateStudent student1 = new UndergraduateStudent("Tom");

GraduateStudent student2 = new GraduateStudent("Dick");


students.add(student1);
students.add(student2);
Misalkan kelas juga memiliki method untuk mendapatkan objek Student
disimpan pada indeks tertentu seperti di bawah ini.
public Student getStudentAt(int index) {
// Return the Student object at position index.
// If index is invalid, return null.
}
Mari kita fokus pada kode berikut yang melintasi daftar dan cek apakah siswa
dalam performa yang baik.
for (int index = 0; index < students.size(); index++) {
if (students.getStudentAt(index).isInGoodStanding()) {
System.out.println(students.get(index).getName()
+ " is in good standing");

} else {
System.out.println(students.getStudentAt(index).getName()
+ " is not in good standing");
}
}
Kami berasumsi bahwa siswa Tom, seorang mahasiswa sarjana, dan Dick, seorang
mahasiswa pascasarjana, berada dalam daftar sesuai dengan kode yang diberikan
do awal. loop akan iterate dua kali, pertama mengakses objek sesuai dengan Tom
dan kemudian mendapatkan objek untuk Dick. Dalam kedua kasus, yaitu dalam
method GoodStanding akan dipanggil.
Kode di atas menunjukkan kekuatan dinamis mengikat. Dalam panggilan
untuk isInGoodStanding, kami tidak menyadari jenis objek. Cukup dengan
memeriksa kode yang memanggil method, kita tidak bisa membedakan mana
definisi method isInGoodStanding akan dipanggil, yaitu dinamis mengikat
memberikan kita kemampuan untuk menyembunyikan rincian ini dalam hirarki
warisan.
3.2.4

Bidang dilindungi dan metode


Pertimbangkan hirarki seperti yang ditunjukkan pada Gambar 3.11.
ClosedFigure memiliki luas atribut yang menyimpan luas benda ClosedFigure.

artinya ini adalah bahwa bidang ini dapat diakses oleh ClosedFigure dan
keturunannya seperti yang ditunjukkan di bawah ini.
public class ClosedFigure extends Figure {
protected double area;
//other fields and methods
}

Figure

ClosedFigure
#area : double

Gambar 3.11 Gambar hierarki


public class Polygon extends ClosedFigure {
public void InsertVertex(Point p, int i) {
ClosedCurve
// code to insert
vertex at position i Polygon
area = computeArea();
}
private double computeArea() {
//code to compute the area
}
}
Contoh di atas adalah sederhana sejak kelas Polygon adalah memodifikasi
bidang objek Polygon. Mempertimbangkan situasi berikut.
public class ClosedCurve {
// other fields and methods
public void areaManipulator(Polygon p) {
p.area = 0.0;
}
}
Di sini ClosedCurve kelas memodifikasi daerah poligon. Definisi yang longgar
kami mengatakan bahwa daerah dapat dilihat ClosedCurve yang akan membuat
ini berlaku. Namun, ClosedCurve, adalah saudara dari Polygon dan karena itu
tidak untuk kendala desain Polygon, dan menyediakan akses tersebut dapat

membahayakan integritas kode kita. Faktanya, klien yang tidak bermoral bisa
dengan mudah melakukan hal berikut:
class BackDoor extends ClosedFigure {
public void setArea(double area, ClosedFigure someClosedFigure) {
someClosedFigure.area = area;
}
}
Oleh karena itu kita perlu definisi berikut ketat dari akses yang dilindungi.
Kode yang berada di kelas A dapat mengakses atribut dilindungi dari sebuah
objek dari kelas B hanya jika B adalah setidaknya tipe A, yaitu B milik hirarki
berakar di A.
3.2.5

Kelas objek
Java memiliki kelas khusus yang disebut Object yang setiap kelas mewarisi.
Dengan kata lain, Obyek adalah superclass dari setiap kelas di Java dan
merupakan akar dari hirarki kelas. Dari pengetahuan kita tentang tugas
polimorfik, kita dapat melihat bahwa variabel bertipe Object dapat menyimpan
referensi ke objek jenis lainnya. Kode berikut demikian hukum.
Object anyObject;
anyObject = new Student();
anyObject = new Integer(4);
anyObject = "Some string";
Dalam contoh di atas, variabel anyObject toko pertama objek Student, maka
obyek Integer, dan akhirnya sebuah objek String.

3.3 Genericity
Genericity adalah mekanisme untuk menciptakan entitas yang berbeda hanya dalam
jenis parameter mereka, dan gagasan ini dapat dikaitkan dengan entitas (kelas atau
metode) yang memerlukan parameter beberapa tipe tertentu.
Untuk memahami kegunaan genericity, mempertimbangkan pelaksanaan berikut:
public class Stack {
private class StackNode {
Object data;
StackNode next;
// rest of the class not shown

}
public void push(Object data) {
// implementation not shown
}
public Object pop() {
// implementation not shown
}
// rest of the class not shown
}
Elemen stack disimpan dalam bidang data StackNode. Perhatikan data yang bertipe
Object, yang berarti bahwa setiap jenis data dapat disimpan di dalamnya.
Kami membuat tumpukan dan menyimpan sebuah objek Integer di dalamnya.
Stack myIntStack = new Stack(); // line 1
myIntStack.push(new Integer(5)); // line 2
Integer x = (Integer) myIntStack.pop(); //line 3
Implementasi ini memiliki beberapa kelemahan. Sejalan 2, tidak ada yang mencegah kita
dari mendorong objek sewenang-wenang dalam stack. Kode berikut, misalnya, adalah
sempurna yang bener.
Stack myIntStack = new Stack();
myIntStack.push("A string");
Kode berikut akan menghasilkan error.
Stack myIntStack = new Stack();
myIntStack.push("A string");
Integer x = (Integer) myIntStack.pop(); // error
Kita bisa menulis kode tambahan yang menangani kesalahan karena para pemain yang
salah, tapi itu tidak membuat kode dibaca. Di sisi lain, kita bisa menulis kelas Stack
terpisah untuk setiap jenis stack yang kita butuhkan, tapi kemudian kami tidak dapat
menggunakan kembali kode kita.
Generik memberikan kita jalan keluar dari dilema ini. Sebuah kelas Stack generik
akan didefinisikan sesuatu seperti ini:
public class Stack<E> {
//code for fields and constructors
public void push(E item) {
// code to push item into stack
}

public E pop() {
// code to push item into stack
}
}
3.4 Diskusi dan Bacaan Lebih Lanjut
Dalam bab ini kita telah membahas bagaimana kelas-kelas dalam sistem berorientasi
obyek berhubungan satu sama lain. Asosiasi adalah yang paling sederhana dan paling
umum. Meskipun bab ini menyentuh pada beberapa aspek asosiasi, penelitian yang lebih
rinci dari notasi UML dan beberapa poin-poin penting dari menggunakan asosiasi akan
diperlukan sebelum memulai sebuah proyek serius. Notasi UML menyediakan
mekanisme untuk jenis lain dari hubungan antara kelas, disebut ketergantungan.
Sebuah pengetahuan mendalam tentang warisan penting untuk siapa pun yang
terlibat dalam OOAD. Sementara gagasan kelas membantu kita menerapkan tipe data
abstrak, itu adalah warisan yang membuat paradigma berorientasi objek begitu kuat.
Mewarisi dari superclass memungkinkan tidak hanya untuk menggunakan kembali kode
yang ada di superclass, tetapi juga untuk melihat contoh dari semua subclass sebagai
anggota dari jenis superclass. tugas polimorfik dikombinasikan dengan mengikat dinamis
metode memungkinkan untuk memungkinkan pengolahan seragam obyek tanpa harus
khawatir tentang jenis mereka dengan tepat.
Ada beberapa overhead yang terkait dengan dinamis mengikat. Dalam C ++,
programmer dapat menentukan bahwa metode adalah virtual, yang berarti bahwa dinamis
mengikat akan digunakan selama pemanggilan metode. Metode tidak didefinisikan
sebagai virtual akan dipanggil menggunakan jenis menyatakan referensi yang digunakan
dalam panggilan. Ini membantu programmer menghindari overhead yang terkait dengan
dinamis mengikat dalam metode panggilan yang tidak benar-benar membutuhkan
kekuatan dinamis mengikat. Dalam C ++ bahasa, semua metode Jawa virtual.
Di Java, penting untuk dicatat bahwa dinamis mengikat tidak terikat subclassing. Hal
ini juga berlaku dalam konteks interface. Misalnya, mempertimbangkan situasi di mana
mahasiswa bukan kelas, tapi antarmuka.
public interface Student {
public boolean isInGoodStanding();
public abstract double getGPACutoff();
public String getName();

// more methods
}
Mari kita berasumsi bahwa antarmuka di atas dilaksanakan oleh UndergraduateStudent
kelas dan GraduateStudent. pelaksanaannya cukup sederhana, sehingga kita tidak
menunjukkan kode untuk itu; satu-satunya perbedaan utama sekarang adalah bahwa
karena tidak ada subclassing, yang isInGoodStanding () dari GraduateStudent tidak bisa
mengeluarkan super panggilan. isInGoodStanding () tetapi harus menghitung secara
lokal.
Sekarang, kode yang diberikan sebelumnya dan direproduksi di bawah ini, bekerja
melalui dinamis mengikat.
for (int index = 0; index < students.size(); index++) {
if (students.getStudentAt(index).isInGoodStanding()) {
System.out.println(students.get(index).getName()
+ " is in good standing");
} else {
System.out.println(students.get(index).getName()
+ " is not in good standing");
}
}
3.4.1

Sebuah gagasan umum dari kesesuaian


Kebanyakan bahasa tingkat tinggi melakukan beberapa jenis tipe pengecekan
ketika tugas dilakukan. pemeriksaan ini digunakan untuk memastikan bahwa jenis
badan dikembalikan oleh ekspresi pada sisi kiri (LHS) penugasan memang bisa
disimpan dalam jenis entitas direferensikan pada RHS. Dengan kata lain, kita
mengatakan bahwa jenis badan dikembalikan oleh ekspresi pada sisi kiri (LHS) dari
tugas sesuai dengan jenis entitas direferensikan pada RHS. Jika kesesuaian tidak ada,
beberapa jenis pengecoran diperlukan, tetapi hasil cetakan tidak dapat dijamin oleh
sebuah compiler karena mereka bergantung pada perilaku run-time.
Dalam konteks warisan, kita telah melihat bahwa subclass sesuai dengan jenis
supernya. Ketika kita menambahkan genericity ke dalam campuran, dan ekspresi pada
LHS mengevaluasi ke sebuah contoh dari entitas didefinisikan secara umum;
parameter generik sesuai dari LHS dan RHS juga harus dalam kesesuaian.
Pemeriksaan ini harus dilakukan secara rekursif sejak parameter bisa sendiri
diturunkan umum [30]. Mengingat definisi berikut,

public class Polygon {


// code for Polygon
}
public class Triangle extends Polygon {
// code for Triangle
}
public class Square extends Polygon {
// code for Square
}
jenis generik Stack <Square> dan Stack <Segitiga> sesuai dengan Stack <Polygon>.
Namun, tugas semacam itu ditunjukkan di bawah ditandai oleh compiler Java.
Stack<Square> ssq = new Stack<Square>();
Stack<Polygon> sp = ssq; // Compiler Error!
Alasan untuk ini tampaknya menjadi yang generik menjadi pengenalan kemudian ke
Jawa, interoperabilitas dengan kode warisan diperlukan. Hal ini dicapai dengan
mekanisme yang disebut penghapusan, yang mengakibatkan semua informasi jenis
generik yang terhapus pada waktu kompilasi. Ini berarti bahwa jika pernyataan di atas
tidak ditandai sebagai kesalahan, tidak ada cara bahwa sistem bisa mencegah
mendorong segitiga pada tumpukan kotak.
Stack<Square> ssq = new Stack<Square>();
Stack<Polygon> sp = ssq;
sp.push(new Triangle()); // no way to detect this
Beberapa bahasa memungkinkan gips dinamis yang merupakan salah satu cara bahwa
situasi ini bisa ditangani. Dalam C ++, misalnya, kode berikut akan mengkompilasi,
tapi menghasilkan kesalahan run-time [3].
Stack<Triangle> * TStack = new Stack<Triangle>();
Stack <Polygon> * PStack;
PStack = dynamic_cast<Stack <Polygon> *> (TStack); // valid, types conform
Square * s1 = new Square();
Polygon * p1 = dynamic_cast<Polygon*>(s1);
PStack->push(*p1); // run-time error
Sistem ini melacak fakta bahwa PStackis pointer ke Stack <Segitiga> dan yang * p1
pada kenyataannya merupakan Square.

BAB 4 (Language Features for Object-Oriented


Implementation)
Dalam bab ini akan dibahas beberapa konsep yaitu :
4.1 Pengorganisasian Classes
class dan interface adalah modul yang menyusun sistem perangkat lunak. Berikut code
untuk mengimpor sebuah member dari sebuah packages :
importjava.util.*;
mengimpor semua members dari sebuah packages tidak mengimpor sub-paket. Sebagai
contoh, meskipun ada packages java.awt
pernyataan
java.awtimpor.

dan

tidak

*;

classjava.awt.image.ColorModel

java.awt.image, dengan

maka

kita

mengimpor
perlu

menulis

import

java.awt.image.*;
4.1.3

Protected access and package access


Penggunaan protected accsess sfecifier pada bab 3. Contoh : field x didefinisikan sebagai
protected pada class C, kemudian field juga dapat diakses di class yang berada dalam
packages yang sama seperti C. Contoh :
package mypackage;
public class C {
protected int x;
}
package mypackage;
import mypackage.C;
public class D {
public void f(C c) {
c.x = 1;
}
}

4.2 Collection Classes


Packages java.util berisi sejumlah interface dan class yang akan digunakan dalam
contoh .Inteface java.util.Collection , misalnya, berisi metode untuk
memanipulasi collection. Beberapa metode dalam interface ini adalah :
1. boolean add(Object object): menambahkan objek yang disediakan
untuk collection.
2. boolean addAll(Collection collection): menambahkan semua
objek dalam collection disediakan ke koleksi ini.
3. void clear():menghapus semua elemen dari collection ini.
4. boolean contains(Object object):mengembalikan nilai true jika dan hanya
jika collection ini berisi objek yang disediakan.
5. int size():mengembalikan jumlah elemen dalam koleksi ini.
6. Metode untuk menghilangkan benda, memeriksa apakah koleksi
kosong, dll
Menggunakan class atas, sangat mudah untuk membuat dan menggunakan list.
Class sederhana berikut membuat urutan objek String, menyimpannya dalam list, dan
mencetak list.
import java.util.*;
public class ListUseExample {
public static void main(String[] s) {
List list = new ArrayList();
for (int count = 1; count <= 10; count++) {
list.add(new String("String " + count));
}
for (int count = 0; count <= 9; count++) {
System.out.println(list.get(count));
}
}
}
Sejak ArrayListmengimplementasikan List interface, kode berikut
adalah legal:
List list = new ArrayList();

4.3 Exception
Jenis tertentu dari objek tergantung pada jenis operasi. Berikut adalah beberapa contoh :
1. Dilakukan usaha untuk mengakses array dengan indeks yang tidak valid.Objek yang
dihasilkanjenisArrayIndexOutOfBoundsException.
2. Sebuah referensi null digunakan untuk mengakses lapangan atau metode objek.Dalam hal
ini, objek yang dihasilkan adalah tipeNullPointerException.
3. Terjadi kesalahan saat operasi input atau output terjadi.Objek dalam hal ini adalah dari
jenisIOException.
4. Upaya untuk melemparkan sebuah objek gagal seperti pada contoh mahasiswa.Jenis
pengecualian disebutClassCastException.
menempatkan kode menyinggung dalam blok try dan menangkap objek pengecualian:
try{
Studentstudent=newUndergraduateStudent();
GraduateStudentgraduateStudent=(GraduateStudent)student;
//processtheobject
}catch(ClassCastExceptioncce){
//Objectisnotoftypegraduatestudent.
//dosomeoperationtorecoverfromtheerror
}
Berikut ini adalah bagian dari kode yang menangani tiga jenis pengecualian:
try {
if (myObject.getField1().equals(someObject)) {
int index = myObject.getIndex();
int value =
Integer.parseInt(JOptionPane.showInputDialog(null,
"Enter a number"));
myArray[index] = value;
} catch (NullPointerException npe) {
System.out.println("Null pointer " + npe);
System.exit(0);

} catch (ArrayIndexOutOfBoundsException aiofbe) {


System.out.println("Array index out of range " + aiofbe);
return;
} catch (NumberFormatException nfe) {
System.out.println("Invalid entry; exception " + nfe);
return;
}
}
4.4 Jenis Run-time Identifikasi
Polimorfisme dan dinamic binding tidak cukup untuk mengurus semua masalah yang
muncul ketika berhadapan dengan inheritance hierarchy. Perhatikan, misalnya, kelas
Shape dengan dua subclass, Square dan Lingkaran. ShapeList menjadi koleksi Shape. Jika
kita mengakses item dari collection, itu akan menjadi tipe Shape, apakah itu akan menjadi
Square atau Lingkaran.
Katakanlah, kita memiliki aplikasi yang perlu mengetahui jumlah objek Lingkaran di
koleksi ShapeList. Ini dapat diterapkan sebagai metode umum di ShapeList
public int circleCount ()
atau sebagai metode client yang mengambil referensi ke ShapeList a.
int circleCount (Shapelist shapeList)
4.1.1

Membuat file
File harus diberi nama <class / nama interface> java. Java mensyaratkan
bahwa dengan lebih dari satu class atau interface dalam sebuah file, hanya salah satu
class / interface dapat publik; jika ada class / interface publik dalam sebuah file,
nama kelas / interface harus digunakan untuk penamaan file.

4.1.2

Packages
Sebuah packages adalah kumpulan class. Beberapa packages utama adalah
java.lang, java.util, java.awt, javax.swing, java.io, dan
Java.lang.reflect.
Java secara otomatis dapat membuat class dan interface dalam packages

java.lang. Program yang menggunakan class dari packages lain harus


mengimpor dari paket yang sesuai. Misalnya, menggunakan Vector class yang berada
di java.util, kode harus resor untuk salah satu dari beberapa pendekatan.
Pendekatan pertama : java.util.Vector myVector = baru java.util.Vector ();
Pendekatan kedua : impor java.util.Vector;
4.4.1

Reflection: Using the Class object


Untuk memeriksa apakah objek Shape diberikan adalah Lingkaran
menggunakan metode ini, kita lakukan hal berikut:
Shape; // Kode untuk membuat objek Shape // dan menyimpan referensi
dalam bentuk if (shape.getClass (). GetName (). Equals ( "Circle"))
{//mengambil tindakan yang sesuai}
Metode getClass () didefinisikan oleh java untuk class Object, dan karena
itu secara otomatis tersedia untuk setiap class yang ditetapkan pengguna. Dalam
contoh , getClass mengembalikan sebuah objek yang menyimpan informasi
tentang class Circle, dan metode getName pada objek yang mengembalikan string
"Circle". satu kelemahan: compiler tidak dapat memeriksa kesalahan ketik dalam
string terhadap yang diperiksa. Kode berikut, misalnya, akan mengkompilasi
benar.
bentukShape // Kode untuk membuat s Shape objek // dan menyimpan
referensi dalam bentuk if (shape.getClass (). GetName (). Equals ( "lingkaran"))
{//mengambil tindakan yang tepat}
Mengetik "lingkaran" bukan "Lingkaran "memberi kita jawaban yang
salah karena kesalahan dalam kode tidak bisa ditangkap oleh compiler.

4.4.2

Using the instance of operator


kita menggunakan operator instance of untuk query jenis objek. Kodenya
seperti berikut :
bentuk Shape; // Kode untuk membuat s Shape objek // dan menyimpan referensi
dalam bentuk if (bentuk instanceof Circle) {// mengambil tindakan yang sesuai}

Dalam kasus metode computeTax, kita menciptakan solusi yang sama.


ganda computeTax (investasi Investasi)
{jumlahganda; jika (investasi instanceof Deposit)
{jumlah= (Deposit) investment.getInterest (); // Kode untuk menghitung pajak
atas jumlah} else if (investasi instanceof Stock)
{jumlah= (Stock) investment.getDividend (); // Kode untuk menghitung jumlah
pajak} // kembali pajak}

4.4.3

Downcasting
Memasukkan superclass mengacu ke subclas. Contoh :
computeTax ganda (investasi Investasi)
{jumlahganda; Deposit Deposit = (Deposit) investasi; Jumlah =
deposit.getInterest (); // Kode untuk menghitung pajak atas jumlah // sisa metode
ini tidak ditampilkan}
Meskipun ClassCastException adalah tion RuntimeException dan tidak biasanya
harus ditangkap, ini bisa dianggap sebagai situasi yang tepat di mana ia harus
ditangani. Kita bisa menulis ulang metode seperti di bawah ini :
ganda computeTax (investasi Investasi)
{jumlahganda; try
{DepositDeposit = (Deposit) investasi; Jumlah = deposit.getInterest (); // Kode
untuk menghitung pajak atas jumlah} catch (ClassCastException cce)
{try{saham
Bursa = (Stock) investasi; Jumlah = stock.getInterest (); // Kode untuk
menghitung pajak atas jumlah} catch (ClassCastException cce)
{cce.printStackTrace(); }} // Kembali pajak}
Contoh di atas tampaknya menunjukkan downcasting dan operator instanceof
dapat digunakan secara bergantian.

Anda mungkin juga menyukai