0002
BAB 7
PEMROGRAMAN BERORIENTASI
OBJEK
Tujuan Materi
Setelah menyelesaikan bagian ini anda diharapkan:
9 Mengetahui dan memahami konsep Pemrograman Berorientasi Objek (Object Oriented Programming,
OOP).
9 Mampu membedakan konsep pemrograman tradisional dengan Pemrograman Berorientasi Objek.
9 Mampu menerapkan konsep Pemrograman Berorientasi Objek dalam pembuatan program aplikasi.
9 Mampu mengembangkan program aplikasi dengan konsep Pemrograman Berorientasi Objek.
7.1 Pengantar
Metode Pemrograman Berorientasi Objek (Object Oriented Programming, OOP) menawarkan suatu teknik
pembuatan dan pengembangan program aplikasi dengan cara yang mudah dan menyenangkan. Berbagai
program aplikasi berbasis Windows dibangun menggunakan metode pemrograman ini. Konsep yang
digunakan dalam OOP berbeda dengan metode pemrograman tradisional seperti metode pemrograman
prosedural. Terdapat beberapa aspek yang harus diketahui sehubungan dengan metode OOP. Meski
demikian, metode OOP bukannya tanpa masalah; persoalan besar yang dihadapi dalam metode ini adalah
sulitnya memahami konsep objek beserta aspek-aspek yang terkait, misalnya class, inheritance dan lainlain. Masalah besar lainnya adalah besarnya sumber daya komputer yang diperlukan, misalnya kita
memerlukan memori lebih banyak dibandingkan dengan jika kita membuat program dengan metode
tradisional. Dua buah objek yang identik akan memerlukan dua area memori berbeda walaupun dari sisi
data dan proses keduanya memiliki jumlah dan jenis yang sama. Hal ini disebabkan karena data dan
proses pada kedua objek tersebut dipisahkan oleh komputer.
Bagian ini juga membahas tentang class, yaitu cikal-bakal objek. Class merupakan aspek penting yang
harus diketahui jika anda ingin belajar tentang OOP. Setelah membahas tentang class, secara bertahap
kita juga akan membahas tentang proses pembuatan dan pengembangan objek. Jika anda membutuhkan
informasi lengkap tentang konsep Object Oriented anda bisa membaca referensi yang menjelaskan
konsep Object Oriented murni tanpa merujuk pada sebuah bahasa pemrograman, sedangkan buku ini
mencoba mengimplementasikan konsep Object Oriented menggunakan bahasa Java.
Seluruh materi pada bagian ini akan dijelaskan dengan cara yang mudah dipahami, bahkan mungkin anda
akan menilai bahwa materinya berbeda jauh dengan materi di buku-buku referensi asli yang membahas
metode OOP. Penjelasan yang rumit dan bersifat teoritis akan kita hindari. Jika anda membutuhkan
penjelasan yang lebih detail, anda bisa membaca buku-buku referensi yang khusus membahas tentang
Pemrograman Berorientasi Objek.
Secara lengkap materi-materi yang akan kita bicarakan dalam bab ini adalah:
1. Objek
2. Classification
a. Abstraction
b. Encapsulation
c. Constructor
i. Single constructor
ii. Constructor dengan parameter
iii. Multiple constructor
d. Inheritance
e. Polymorphism
3. Package
4. Contoh Kasus
a. Class Penduduk
b. Class Karyawan
c. Class Mahasiswa
d. Class Menwa
-1-
7.2 Objek
Terdapat fungsi untuk menghitung luas lingkaran dengan rumus yang sudah dikenal luas: .r2. Notasi
atau phi adalah konstanta sedangkan r adalah variabel, sehingga hasil perhitungan akan sangat
ditentukan oleh besar kecilnya nilai r, atau dengan kata lain hasil perhitungan berbanding lurus dengan
perubahan nilai r.
ja ri-ja ri ( r )
xr
lu a s lin g k a ra n
Fungsi menghitung luas lingkaran ini membutuhkan data jari-jari lingkaran. Sekarang asumsikan ada tiga
lingkaran yang akan kita hitung luasnya, masing-masing dengan nilai jari-jari 5, 20 dan 34. Dengan
pendekatan 5 angka desimal perhitungan luas ketiga lingkaran tersebut diperlihatkan sebagai berikut:
D a ta ja r i-ja r i 5 > > >
x5
Luas = 78.53982
20
x 20
Luas = 1256.63706
34
x 34
Luas = 3631.68111
Melalui fungsi yang sama bisa diperoleh hasil perhitungan yang berbeda-beda tergantung data masukan
yang diberikan. Lebih jauh lagi, seandainya suatu ketika ada perubahan rumus menghitung luas lingkaran,
maka perubahan tersebut akan berdampak pada tiga lingkaran tersebut. Hal ini bisa dianalogikan dengan
mesin parut kelapa: jika mesin tersebut mengalami perubahan desain misalnya, maka perubahan tersebut
akan berdampak pada orang-orang yang memarut kelapa dengan mesin tersebut.
lainnya.
7.3 Classification
Sebuah pabrik garmen menerima order pembuatan kaos bergambar sebanyak 100 buah. Keseratus kaos
tersebut akan diberi gambar donald-bebek. Dengan alasan menghemat biaya dan efisiensi waktu, pihak
pabrik akan membuat satu model gambar saja. Pada model gambar ini pabrik garmen melakukan desain
gambar, pengaturan warna dan hal-hal lain yang diperlukan sehubungan dengan gambar sablon yang
akan ditempelkan di kaos. Pihak pabrik tidak perlu membuat 100 model gambar donald-bebek untuk 100
kaos, cukup satu gambar untuk seluruh kaos. Pembuatan model kaos harus memperhitungkan ongkos
-2-
menggambar, ongkos bahan warna dan sebagainya, sehingga lebih efisien jika model yang dibuat hanya
satu untuk kemudian di-copy-paste pada beberapa kaos.
Dari ilustrasi ini ada dua hal yang bisa diketahui:
Ada sebuah cetakan atau model. Cetakan ini bersifat abstrak, tidak bisa digunakan oleh user,
karena cetakan ini bukanlah benda yang bisa dipakai. Cetakan sablon ini identik dengan class.
[pernahkan anda membayangkan membeli barang menggunakan cetakan uang ?]
Ada kaos yang akan dijadikan sasaran mewujudkan cetakan tersebut. Kaos ini bersifat kongkrit,
bisa dilihat dan digunakan. Kaos yang disablon tidak lain adalah objek. [sehari-hari anda membeli
barang dengan uang yang nyata]
Blok program ini merupakan bentuk dasar pembentukan class di Java. Pada bagian selanjutnya kita akan
mengimplementasikan bentuk tersebut dengan kasus yang lebih real.
Sebuah class (atau objek nantinya) memiliki dua komponen:
1. Data member (anggota data), yaitu variabel-variabel yang menyatakan karakteristik suatu objek.
Sebuah objek lingkaran memiliki karakteristik yang dinyatakan dengan nilai jari-jari.
2. Member function (fungsi anggota), yaitu fungsi-fungsi yang bertugas memanipulasi nilai pada datamember. Fungsi yang paling sering ada pada sebuah objek adalah fungsi untuk mengubah dan
menginformasikan nilai dari data-member objek.
7.3.1 Abstraction
Abstraction adalah suatu proses dimana kita melakukan desain class dan menentukan data dan method
yang akan dimiliki oleh sebuah class. Sebuah bangun geometri lingkaran dideskripsikan dengan bentuk
seperti di bawah ini:
Sekarang anda bayangkan terdapat beberapa lingkaran. Setiap lingkaran memiliki jari-jari. Nilai jari-jari
tersebut mungkin sama mungkin juga berbeda, yang pasti adalah setiap lingkaran memiliki jari-jari. Nilai
jari-jari sebuah lingkaran bersifat bebas, tidak tergantung pada nilai jari-jari lingkaran lain. Jadi jari-jari
adalah data yang dimiliki oleh sembarang lingkaran, dan inilah yang menjadi karakteristik bangun geometri
lingkaran.
Berdasarkan fakta ini maka kita bisa membuat class untuk objek lingkaran. Class ini kita beri nama
Lingkaran, disesuaikan dengan nama bangun geometri yang akan kita buat. (anda bebas memberi nama
sesuai keinginan). Class Lingkaran ini memiliki karakteristik sebagai berikut:
-3-
1. Memiliki jari-jari.
2. Memiliki beberapa method:
9 Mengubah nilai jari-jari,
9 Memperoleh informasi jari-jari,
9 Menghitung luas lingkaran,
9 Menghitung keliling lingkaran.
Langkah
berikutnya
adalah
membuat format class Lingkaran
berdasarkan
karakteristik
tersebut di atas.
class Lingkaran
{
data: jari-jari
method: update jari-jari
informasi jari-jari
hitung luas
hitung keliling
}
Sampai di sini tahap perancangan class bisa dianggap selesai. Pada bagian selanjutnya kita akan
melakukan implementasi class ini secara mendetail.
7.3.2 Encapsulation
Data yang ada pada suatu objek tidak boleh diubah secara langsung
dari luar objek tersebut. Perubahan secara langsung dari luar objek bisa
berakibat data-data di dalam objek mengalami kondisi bad value yang
pada akhirnya berimbas pada tidak berfungsinya sebuah objek
sebagaimana yang dikehendaki. Di satu sisi kita tidak bisa menjamin
bahwa pengguna objek akan memasukkan data-data yang valid;
seringkali programmer terjangkit penyakit iseng, mencoba hal-hal yang
dianggap baru. Pada saat anda diminta memasukkan password untuk
sebuah software, kemungkinan besar anda akan mencoba memasukkan data sembarang, dengan
harapan data itu benar.
Encapsulation merupakan
inti dari metode OOP
dimana data objek
dilindungi dari perubahan
secara langsung dari luar
Di sisi lain kita yakin bahwa suatu ketika lingkungan luar memerlukan informasi dari objek kita, atau
mungkin lingkungan luar ingin mengubah informasi yang tersimpan di dalam objek. Dengan demikian
harus ada mekanisme untuk mengubah data objek dan menginformasikan data tersebut ke lingkungan
luar. Proteksi terhadap data objek harus diiringi dengan mekanisme untuk mengakses data tersebut.
Memang tidak semua data yang ada di dalam objek boleh diperkenalkan ke lingkungan luar; kita harus
selektif menentukan data mana yang boleh diakses dan data mana yang tidak boleh diakses dari luar.
Dengan sering berlatih anda akan mampu secara cepat menentukan data mana yang boleh di-publish ke
luar dan data mana yang hanya boleh diketahui oleh lingkungan dalam objek.
Kembali kepada contoh tentang lingkaran, nilai jari-jari haruslah dinamis, tidak boleh statis. Walaupun
demikian perlu disadari bahwa nilai jari-jari tersebut tidak boleh negatif atau nol, karena tidak mungkin
sebuah bangun geometri berdimensi nol atau negatif. Jika data jari-jari di-publish secara umum ke luar
objek, maka ada kemungkinan user akan memberi nilai nol atau negatif ke dalamnya. Untuk mengatasi ini
kita harus menyediakan method khusus yang menangani perubahan nilai jari-jari ini. Di dalam method ini
ada mekanisme untuk memeriksa validitas data jari-jari yang baru masuk. Jika data tersebut valid, proses
perubahan akan dilanjutkan dengan mengubah nilai jari-jari sesuai dengan data yang baru masuk tersebut.
Tetapi jika ternyata data yang masuk tidak valid, objek akan menolak data tersebut dan mempertahankan
nilai sebelumnya.
Berikut ini diberikan kode program untuk class Lingkaran secara lengkap. Perhatikan bagaimana kita
melakukan pengamanan terhadap data objek. Kata kunci private digunakan untuk mengunci data atau
method agar tidak terlihat dari luar objek. Sebaliknya, kata kunci public digunakan untuk mem-publish data
atau method agar dikenal dari luar objek.
-4-
Program 7.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Lingkaran
{
private double jariJari;
public void setJariJari (double r)
{
if (r > 0) jariJari = r;
}
public double getJariJari()
{
return (jariJari);
}
public double hitungLuas()
{
return (Math.PI * jariJari * jariJari);
}
public double hitungKeliling()
{
return (Math.PI * 2.0 * jariJari);
}
}
Penamaan method mengikuti ciri-ciri dari kebanyakan perintah standar Java. Ciri-ciri tersebut adalah:
1. Method yang bertugas mengubah nilai ke dalam objek diberi awalan set, misalnya setJariJari(). Nama
method setelah kata set sama dengan nama variabel data objek yang akan diubah nilainya, misalnya
setJariJari() menyatakan bahwa data yang akan diubah adalah nilai dari data objek bernama jariJari.
2. Method yang bertugas mengambil nilai dari dalam objek diberi awalan get, misalnya getLuas().Nama
method setelah kata get sama dengan nama variabel data objek yang akan diketahui nilainya,
misalnya getJariJari() menyatakan bahwa data yang akan diketahui nilainya adalah data objek
bernama jariJari.
3. Method dengan tugas selain point 1 dan 2 akan diberi nama sesuai dengan tugas yang dikerjakan oleh
method tersebut.
Instruksi pada baris 3 menyatakan bahwa kita mendeklarasikan variabel jariJari dengan scope lokal,
artinya variabel ini hanya dikenal di dalam class Lingkaran. Lingkungan luar class (atau objek) tidak
mengenal variabel ini sehingga kita perlu menyediakan method yang berguna untuk mengkomunikasikan
data jari-jari dengan lingkungan luar class. Method setJariJari(double) digunakan untuk mengubah nilai
jariJari (baris 10-13) dan method getJariJari() digunakan untuk memperoleh nilai jari-jari yang sedang aktif
pada objek lingkaran (baris 15-18).
Secara bagan kita bisa menggambarkan class Lingkaran ini dengan bentuk sebagai berikut:
Lingkaran
double jariJari
void setJariJari (double)
double getJariJari()
double hitungLuas()
double hitungKeliling()
7.3.3 Constructor
Setelah kita mendeklarasikan sebuah variabel, apakah kita yakin mengenai nilai awal yang disimpan di
dalam variabel tersebut ? Tanpa memberinya nilai awal, yakinkah kita bahwa mula-mula variabel tersebut
-5-
menyimpan data nol ? Bagi anda yang pernah menggunakan bahasa pemrograman selain Java, tentunya
anda berasumsi bahwa Java akan menetapkan nilai nol sebagai nilai awal numerik dan string kosong (nullstring) sebagai nilai awal data string. Tentu anda masih ingat materi di buku jilid 1 bagaimana ketatnya
Java terhadap variabel yang tidak diberi nilai awal.
Pada saat kita membuat sebuah class, kita harus bisa memastikan tentang nilai awal yang disimpan oleh
seluruh data objek nantinya. Karena data objek menunjukkan karakteristik objek tersebut, maka seluruh
nilai yang tersimpan di dalamnya haruslah logis dan valid, misalnya jari-jari lingkaran tidak boleh nol atau
negatif. Secara mudah bisa kita katakan bahwa kita akan membuat sebuah method yang berfungsi untuk
mengubah nilai seluruh data objek, katakanlah method bernama initAllValue(). Itu betul, tetapi yang
menjadi persoalan adalah bagaimana nilai awal yang disimpan oleh data objek pada saat objek tersebut
baru diciptakan, bukan pada saat objek sudah ada. Method initAllValue() hanya bisa dipanggil pada saat
objek sudah ada, bukan pada saat objek baru dibuat.
Metode OOP hadir dengan adanya sebuah method khusus yang disebut constructor yang akan dipanggil
secara otomatis pada saat sebuah objek diciptakan. Kita tidak usah melakukan pemanggilan terhadap
constructor ini; Java-lah yang akan melakukannya. Keunikan ini bisa kita manfaatkan untuk melakukan
proses inisialisasi seluruh data objek. Dengan kata lain proses pemberian nilai awal seluruh data objek
dilakukan melalui constructor. Isi constructor itu sendiri bisa berupa pemanggilan method internal atau
instruksi lain.
Sebagaimana fungsi atau method pada umumnya, constructor juga bisa memiliki variasi parameter. Kita
bisa menerapkan konsep function-overloading pada constructor. Secara umum ada tiga variasi
constructor:
1. Single constructor, yaitu hanya ada satu constructor pada class.
2. Constructor dengan parameter, yaitu constructor dengan data yang bisa kita kirim pada saat
penciptaan objek.
3. Multiple constructor, yaitu terdapat beberapa constructor yang bisa kita pilih pada saat penciptaan
objek.
Program 7.2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
-6-
class Lingkaran
{
private double jariJari;
public Lingkaran()
{
setJariJari (1);
}
public void setJariJari (double r)
{
if (r > 0) jariJari = r;
}
public double getJariJari()
{
return (jariJari);
}
public double hitungLuas()
{
return (Math.PI * jariJari * jariJari);
23
24
25
26
27
28
29
}
public double hitungKeliling()
{
return (Math.PI * 2.0 * jariJari);
}
}
Baris 5 sampai 8 mengimplementasikan penggunaan constructor sebagai proses inisialisasi data objek. Di
sini constructor berisi instruksi yang memanggil method internal setJariJari(). Kita tetap menggunakan
method setJariJari() sebagai method pengubah nilai objek, hanya saja lokasi pemanggilannya dilakukan
melalui constructor dan waktu eksekusinya adalah pada saat objek baru diciptakan.
Karakteristik constructor:
1. Didefinisikan public
2. Memiliki nama sama
dengan nama class
Kedua program 7.1 dan 7.2 bisa kita compile tanpa kesalahan tapi tidak
bisa kita jalankan karena kode-kode tersebut hanya merupakan
implementasi class. Dengan kata lain kita baru saja membuat sebuah
modul bernama Lingkaran. Jika anda mencoba menjalankan kedua
program ini Java akan menampilkan pesan kesalahan yang
menyatakan bahwa fungsi main() tidak ada dalam file.
Solusinya adalah kita harus membuat sebuah class lain yang berisi rutin program yaitu class dengan
fungsi main(). Class baru ini memiliki karakteristik sebagai berikut:
Dideklarasikan sebagai class public.
Nama class menjadi nama file.
Berisi seluruh kode class Lingkaran. [anda bisa melakukan copy-and-paste seluruh kode class
Lingkaran untuk menghemat waktu]
Program 7.3 berikut ini merupakan program lengkap yang bisa dicompile dan dijalankan. Program ini kita
beri nama CobaLingkaran_1 sesuai dengan nama class utamanya: CobaLingkaran_1. Kami akan
menunjukkan bagaimana 3 (tiga) buah objek bertipe lingkaran dapat dibuat sekaligus hanya dengan
mendefinisikan satu class.
Program 7.3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Lingkaran
{
private double jariJari;
public Lingkaran()
{
setJariJari (1);
}
public void setJariJari (double r)
{
if (r > 0) jariJari = r;
}
public double getJariJari()
{
return (jariJari);
}
public double hitungLuas()
{
return (Math.PI * jariJari * jariJari);
}
public double hitungKeliling()
{
return (Math.PI * 2.0 * jariJari);
}
}
public class CobaLingkaran_1
{
-7-
33
34
35
36
37
38
39
40
41
new Lingkaran();
new Lingkaran();
new Lingkaran();
42
43
44
45
46
47
48
49
50
51
52
abc.setJariJari (5);
pqr.setJariJari (3.2);
xyz.setJariJari (1.8);
System.out.println ("Data sekarang :");
System.out.println ("---------------");
System.out.println ("Jari-jari ABC : " +
abc.getJariJari());
System.out.println ("Jari-jari PQR : " +
pqr.getJariJari());
System.out.println ("Jari-jari XYZ : " +
xyz.getJariJari());
System.out.println();
53
54
55
56
57
}
}
Mula-mula ketiga objek lingkaran abc, pqr dan xyz memiliki data jari-jari yang sama seperti yang ditentukan
melalui constructor class. Kemudian ketiga data ini kita ganti dengan nilai yang baru. Output program 7.3
diperlihatkan berikut ini:
abc, pqr dan xyz adalah tiga objek yang berbeda sekalipun berasal dari class yang sama. Perubahan data
pada salah satu objek tidak berpengaruh pada objek yang lain. Anda bisa membuat objek sebanyak yang
anda inginkan.
Sekarang kita akan meringkas dua pekerjaan ini menjadi satu: menentukan data jari-jari langsung pada
saat penciptaan objek. Dalam hal ini kita akan menyisipkan parameter pada constructor, sehingga program
7.3 kita modifikasi menjadi program 7.4 berikut ini. Agar anda tidak rancu dengan program sebelumnya,
program 7.4 ini kita beri nama CobaLingkaran_2.
Program 7.4
-8-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class Lingkaran
{
private double jariJari;
public Lingkaran (double r)
{
if (r > 0)
jariJari = r;
else
jariJari = 1.0;
}
public void setJariJari (double r)
{
if (r > 0) jariJari = r;
}
public double getJariJari()
{
return (jariJari);
}
public double hitungLuas()
{
return (Math.PI * jariJari * jariJari);
}
public double hitungKeliling()
{
return (Math.PI * 2.0 * jariJari);
}
}
public class CobaLingkaran_2
{
public static void main (String[] args)
{
Lingkaran abc = new Lingkaran(5);
Lingkaran pqr = new Lingkaran(3.2);
Lingkaran xyz = new Lingkaran(1.8);
System.out.println ("Data default :");
System.out.println ("--------------");
System.out.println ("Jari-jari ABC : " +
abc.getJariJari());
System.out.println ("Jari-jari PQR : " +
pqr.getJariJari());
System.out.println ("Jari-jari XYZ : " +
xyz.getJariJari());
System.out.println();
45
46
47
48
49
}
}
Modifikasi constructor tampak pada baris 5-10. Dampaknya adalah bagian deklarasi objek (baris 37-39)
ikut berubah karena constructor yang ada sekarang mengharuskan pengiriman data.
-9-
Program 7.5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class Lingkaran
{
private double jariJari;
public Lingkaran()
{
setJariJari (1);
}
public Lingkaran (double r)
{
if (r > 0)
jariJari = r;
else
jariJari = 1.0;
}
public void setJariJari (double r)
{
if (r > 0) jariJari = r;
}
public double getJariJari()
{
return (jariJari);
}
public double hitungLuas()
{
return (Math.PI * jariJari * jariJari);
}
public double hitungKeliling()
{
return (Math.PI * 2.0 * jariJari);
}
}
public class CobaLingkaran_3
{
public static void main (String[] args)
{
Lingkaran abc = new Lingkaran(5);
Lingkaran pqr = new Lingkaran(3.2);
System.out.println ("Data default :");
System.out.println ("--------------");
System.out.println ("Jari-jari ABC : " +
abc.getJariJari());
System.out.println ("Jari-jari PQR : " +
pqr.getJariJari());
System.out.println();
49
50
51
52
}
}
Baris 5-8 merupakan constructor pertama: tanpa parameter. Di dalamnya kita menentukan nilai jari-jari
default sama dengan satu. Kemudian pada baris 10-16 kita membuat constructor model kedua:
berparameter. Baris 43 dan 44 menunjukkan bagaimana penciptaan objek dapat dilakukan dengan
memanggil salah satu dari dua constructor yang ada.
Secara tidak langsung objek abc akan diinisialisasi dengan data 1.0 karena objek ini dibuat tanpa
menyertakan data awal untuk jari-jari.
7.3.4 Inheritance
Inheritance bisa diterjemahkan secara bebas sebagai pewarisan. Yang dimaksud dengan inheritance
adalah konsep dimana kita bisa membuat sebuah class baru dengan mengembangkan class yang pernah
- 10 -
dibuat sebelumnya, bisa jadi class lama tersebut dibuat oleh pihak lain. Metode OOP memungkinkan kita
memperoleh seluruh data dari class induk (base-class) untuk diberikan kepada class anak (derived-class)
tanpa harus melakukan copy-and-paste seluruh kode base-class.
Kita ambil contoh sebagai berikut. Kita akan membuat class Silinder. Sebuah bangun geometri silinder
bisa digambar sebagai berikut:
Berdasarkan gambar tersebut kita bisa membuat bagan untuk class Silinder dengan mencantumkan
seluruh data dan methodnya.
Silinder
double jariJari
double tinggi
void setJariJari (double)
void setTinggi (double)
double getJariJari()
double getTinggi()
double hitungLuas()
double hitungVolume()
Sekarang kita bandingkan class Lingkaran yang telah kita buat sebelum ini dengan class Silinder yang akan
kita buat. Untuk memudahkan pembaca kedua class tersebut kami tampilkan berdampingan.
Lingkaran
double jariJari
void setJariJari (double)
double getJariJari()
double hitungLuas()
double hitungKeliling()
Silinder
double jariJari
double tinggi
void setJariJari (double)
void setTinggi (double)
double getJariJari()
double getTinggi()
double hitungLuas()
double hitungVolume()
Dari perbandingan tersebut kita melihat ada data dan method yang sama pada kedua class. Kita juga bisa
melihat bahwa class Silinder merupakan superset dari class Lingkaran. Metode OOP mengijinkan kita untuk
membuang data dan method dari class superset yang ada pada class subset-nya. Secara otomatis seluruh
data dan method dari class subset disalinkan ke class superset-nya.
- 11 -
Lingkaran
Silinder
double jariJari
double tinggi
Tidak semua method class Lingkaran kita hilangkan pada class Silinder. Method hitungLuas() tetap
digunakan, hanya saja isinya berbeda, karena menghitung luas lingkaran tentu berbeda dengan
menghitung luas silinder. Pada class Silinder kita menambahkan method hitungVolume(), karena bangun
geometri silinder adalah 3-dimensi. Untuk method hitungKeliling(), meskipun pada class Silinder sudah
kita buang, namun user tetap bisa menggunakannya karena method ini secara otomatis diwariskan ke
class Silinder. Padahal kita tahu silinder tidak memiliki keliling.
Struktur kedua class ini bisa digambarkan secara hirarki sebagai berikut, mengikuti model Unified
Modelling Language (UML) dari Rumbaugh dkk:
Lingkaran
double jariJari
void setJariJari (double)
double getJariJari()
double hitungLuas()
double hitungKeliling()
Silinder
double tinggi
void setTinggi (double)
double getTinggi()
double hitungLuas()
double hitungVolume()
Program 7.6 berikut ini merupakan implementasi Java untuk class Silinder.
Program 7.6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- 12 -
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Kata kunci extends menyatakan bahwa suatu class merupakan turunan dari class lain. Pada baris 1 kita
mendefinisikan class Silinder sebagai turunan dari class Lingkaran.
Kemudian, constructor pada class Silinder kita buat dua buah. Pertimbangan kita adalah class ini memiliki
dua buah data, jari-jari dan tinggi, sehingga data yang bisa diinisialisasi ada dua. Sebenarnya kita harus
menyiapkan 4 (empat) constructor.
Constructor pertama menginisialisasi data dengan nilai default.
Constructor kedua menginisialisasi data jari-jari alas silinder.
Constructor ketiga menginisialisasi data tinggi silinder.
Constructor keempat menginisialisasi kedua data jari-jari dan tinggi silinder.
Yang kemudian menjadi persoalan adalah constructor kedua dan ketiga memerlukan sebuah data dengan
tipe sama: double. Penulisan dua constructor seperti ini
Silinder (double r)
Silinder (double t)
dan
memiliki makna yang sama. Java tidak menilai dua constructor tersebut sebagai dua constructor berbeda,
walaupun kita memberi nama parameter berbeda. Yang menjadi titik beratnya adalah tipe data kedua
parameter di atas sama, sehingga kedua constructor tersebut dianggap hanya ada satu. Dengan alasan ini
maka kita hanya membuat constructor pertama dan keempat pada class Silinder.
Agar program 7.6 bisa di-compile anda harus menyisipkan seluruh kode class Lingkaran (copy-and-paste)
dan meletakkannya di atas class Silinder. Selain itu program ini belum bisa dijalankan karena belum
memiliki fungsi main(). Secara lengkap program 7.6 ditulis menjadi program 7.7 berikut ini.
Program 7.7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
- 13 -
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
}
public double hitungKeliling()
{
return (Math.PI * 2.0 * jariJari);
}
}
//--------------------------// Definisi class Silinder
//--------------------------class Silinder extends Lingkaran
{
private double tinggi;
public Silinder()
{
setJariJari (1);
setTinggi (1);
}
public Silinder (double r, double t)
{
setJariJari (r);
setTinggi (t);
}
public void setTinggi (double t)
{
if (t > 0) tinggi = t;
}
public double getTinggi()
{
return (tinggi);
}
public double hitungLuas()
{
return ( super.hitungLuas() * 2.0 +
super.hitungKeliling() * tinggi );
}
public double hitungKeliling()
{
return (Math.PI * 2.0 * jariJari);
}
}
//-----------------------// Definisi class utama
//-----------------------public class CobaSilinder
{
public static void main (String[] args)
{
Silinder abc = new Silinder();
Silinder xyz = new Silinder(23.5, 73.1);
System.out.println ("Data silinder ABC:");
System.out.println ("------------------");
System.out.println (" * Jari-jari : " +
abc.getJariJari());
System.out.println (" * Tinggi
: " +
abc.getTinggi());
System.out.println (" * Luas
: " +
abc.hitungLuas());
System.out.println (" * Volume
: " +
abc.hitungVolume());
System.out.println();
87
88
89
90
91
92
93
94
95
96
97
98
99
100
}
}
Output program:
- 14 -
System.out.println (abc.hitungKeliling());
Kita tahu bahwa benda 3-dimensi tidak memiliki keliling karena bentuk-ruangnya. Kenyataannya, kita
masih bisa mengakses method untuk menghitung kelilingnya. Dalam kasus seperti ini kita harus
membatasi pewarisan data atau method agar tidak bisa diakses dari luar namun tetap bisa diwariskan ke
class di bawahnya.
Modifikasi perlu dilakukan di class Lingkaran. [hanya ditampilkan seperlunya]
33
34
35
36
Kata kunci protected digunakan untuk membuat pertahanan baru dengan membatasi akses ke data atau
method pada suatu class hanya untuk class turunannya saja, tidak termasuk ke bagian lain yang hanya
menggunakan class tersebut. Class Lingkaran yang telah mengalami perubahan ini harus di-compile ulang,
begitu juga dengan class Silinder sebagai class turunannya harus di-compile ulang.
Sekarang, jika di dalam program utama kita memberikan instruksi
System.out.println (abc.hitungKeliling());
Maka pada saat proses compile komputer akan memberikan pesan kesalahan
Method untuk menghitung keliling lingkaran sudah tidak bisa diakses karena method ini didefinisikan
secara protected.
- 15 -
7.3.5 Polymorphism
Secara mudah polymorphism bisa disamakan dengan method-overloading, dimana di dalam sebuah class
terdapat beberapa method dengan nama sama. [lihat materi function-overloading pada buku jilid 1]
Sebuah method bernama tulisData() yang berfungsi menampilkan data string misalnya, tentu tidak bisa
menangani masukan berupa data numerik, boolean maupun karakter; demikian juga sebaliknya. Solusi
yang bisa dilakukan adalah dengan menyediakan beberapa method tulisData() yang akan menangani
setiap tipe data, sehingga data apa pun yang diberikan sebagai parameter tetap bisa diproses.
Perhatikan contoh berikut ini:
Program 7.8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
: ");
: ");
}
}
Output program:
Method tulisData() akan bereaksi dengan satu dari 4 (empat) macam cara tergantung dari data yang
dipassing ke dalamnya. Keragaman model aksi ini disebut polymorph atau banyak-bentuk.
- 16 -
Program 7.8 juga bisa dimodifikasi sebagai berikut: [perhatikan baris 13, 18 dan 23]
Program 7.9
Instruksi baris 13, 18 dan 23 kita ubah dengan memanggil method tulisData() yang mengolah data string
(baris 8). Di sini setiap data yang masuk diubah menjadi data string terlebih dulu baru kemudian
ditampilkan ke layar. Program ini memberikan output sama seperti program 7.8 di atas.
7.4 Package
Sejauh ini seluruh class yang kita buat harus menyatu dengan program utama [class dengan fungsi
main()]. Sebuah program yang baik haruslah mampu menggunakan modul atau class dari file lain tanpa
harus menyalin file tersebut ke dalam file yang sedang di-edit. Java dan beberapa bahasa pemrograman
tradisional menyediakan sarana untuk melakukan hal ini. Perbedaan di antara bahasa pemrograman ini
hanya pada istilah untuk menyebutkan file modul tersebut. Bahasa Basic menggunakan istilah chain,
bahasa Pascal menggunakan istilah unit atau include, bahasa C/C++ menggunakan istilah header,
sementara Java menggunakan istilah package.
Package adalah sebuah directory yang berisi sekumpulan file .class dengan kegunaan spesifik. Berbeda
dengan bahasa lain, Java mengorganisasikan package dalam bentuk directory, dimana di dalam directory
ini bisa terdapat satu atau lebih file java yang telah di-compile atau dalam bentuk .class. Di dalam directory
tersebut bisa juga terdapat satu atau lebih sub-directory yang memiliki file .class atau sub-directory lain.
Proses pembentukan directory package tidak sama dengan pembuatan directory [atau folder] yang selama
ini kita kenal. Barangkali kita terbiasa menggunakan software Windows Explorer untuk membuat directory,
atau menggunakan perintah MD pada sistem operasi DOS. Class yang akan kita masukkan ke dalam
package harus mencantumkan nama package di baris pertama. Secara otomatis file hasil compilenya
akan dimasukkan ke dalam directory yang tidak lain nama package tersebut.
Instruksi untuk meng-compile class Java menjadi package adalah
directory_target tidak sama dengan nama package. Opsi ini digunakan untuk mengarahkan di directory
mana kita akan membuat directory baru sebagai nama package. Anda bisa melakukan setting EditPlus
agar bisa meng-compile package dengan cara berikut:
- 17 -
Nama directory tidak boleh mengandung spasi atau karakter lain yang tidak valid.
Di atas kita telah membuat dua class: Lingkaran dan Silinder. Sekarang kita akan membuat kedua class
tersebut menjadi package agar program lain yang menggunakannya tidak menyertakan kode kedua class
ini di dalamnya.
Mula-mula kita akan memodifikasi class Lingkaran.
Program 7.10
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
10
11
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package modul;
public class Lingkaran
{
private double jariJari;
public Lingkaran()
{
setJariJari (1);
}
public Lingkaran (double r)
{
if (r > 0)
jariJari = r;
else
jariJari = 1.0;
}
public void setJariJari (double r)
{
if (r > 0) jariJari = r;
}
public double getJariJari()
{
return (jariJari);
}
public double hitungLuas()
{
return (Math.PI * jariJari * jariJari);
}
public double hitungKeliling()
{
return (Math.PI * 2.0 * jariJari);
}
}
Karakteristik package:
1. Bersifat public
2. Diawali dengan huruf
kecil
- 18 -
Sekarang kita compile class Lingkaran yang sudah dimodifikasi menjadi package. Tampilan berikut
merupakan kondisi di komputer kami setelah proses compile dilakukan.
Sebuah directory bernama modul telah dibuat secara otomatis oleh Java. Apa isinya ?
Ternyata file Lingkaran.class yang merupakan hasil compile dari Lingkaran.java ada di dalam directory
modul, bukan di directory yang sama dengan file javanya seperti yang selama ini kita ketahui.
Kita teruskan dengan melakukan modifikasi class Silinder. Beberapa hal harus kita pahami terlebih dulu:
Class Silinder merupakan turunan dari class Lingkaran.
Class Lingkaran harus sudah dicompile terlebih dulu, dan ini sudah kita lakukan.
Di dalam class Silinder harus ada instruksi yang mengarahkan Java agar mengambil modul
Lingkaran dari directory modul.
Class Silinder itu sendiri harus menyertakan package modul agar hasil compile-nya disimpan di
directory modul. Karena directory modul sudah ada sebelumnya maka penyertaan ini hanya akan
menambahkan daftar file .class ke dalam directory modul, bukan membuat directory baru bernama
modul.
Berikut ini kode class Silinder yang telah mengalami modifikasi:
Program 7.11
1
2
3
package modul;
import modul.Lingkaran;
- 19 -
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
Kata kunci import digunakan untuk menyatakan bahwa file ini menggunakan modul dari suatu package.
Setelah file ini di-compile kondisi directory menjadi :
Sekarang di dalam directory modul ada dua file .class. Setiap file java yang didesain sebagai package
modul akan menambah daftar file ini.
Implementasi penggunaan sebuah package tidak sulit. Cukup dengan meng-import package yang
dikehendaki, jadilah sudah. Berikut ini adalah contoh penggunaan class Lingkaran seperti program 7.5.
Program 7.12
1
2
3
4
5
6
7
8
9
10
11
12
- 20 -
import modul.Lingkaran;
public class UjiLingkaran
{
public static void main (String[] args)
{
Lingkaran abc = new Lingkaran(5);
Lingkaran pqr = new Lingkaran(3.2);
System.out.println ("Data default :");
System.out.println ("--------------");
System.out.println ("Jari-jari ABC : " +
abc.getJariJari());
13
14
15
16
Output program:
- 21 -
Penduduk
String nama
short tanggalLahir
short bulanLahir
int tahunLahir
char status
boolean jenisKelamin
String getNama()
String getDataLahir()
String getInfoDataLahir()
char getStatus()
String getInfoStatus()
boolean getJenisKelamin()
String getInfoJenisKelamin()
void setNama(String)
void setDataLahir(short,short,int)
void setStatus(char)
void setJenisKelamin(boolean)
void informasi()
Kemudian kita buat listing program Java untuk class Penduduk tersebut. Class ini kita simpan ke dalam
package modul seperti dua class sebelumnya.
Program 7.13
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
- 22 -
package modul;
//--------------------------// Definisi class Penduduk
//--------------------------public class Penduduk
{
private String nama;
private short tanggalLahir;
private short bulanLahir;
private int tahunLahir;
private char status;
private boolean jenisKelamin;
public Penduduk()
{
nama = "NONAME";
tanggalLahir = 1;
bulanLahir = 1;
tahunLahir = 2003;
status = 'B';
jenisKelamin = true;
}
private String getNama()
{
return (nama);
}
public String getDataLahir()
{
return ( Short.toString(tanggalLahir) + '-' +
Short.toString(bulanLahir) + '-' +
Integer.toString(tahunLahir) );
}
public String getInfoDataLahir()
{
String s1 = Short.toString(tanggalLahir);
String s2 = ;
String s3 = Integer.toString(tahunLahir)
switch (bulanLahir)
{
case 1 : s2 = Januari; break;
case 2 : s2 = Februari; break;
case 3 : s2 = Maret; break;
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
case 4 : s2
case 5 : s2
case 6 : s2
case 7 : s2
case 8 : s2
case 9 : s2
case 10 : s2
case 11 : s2
case 12 : s2
April; break;
Mei; break;
Juni; break;
Juli; break;
Agustus; break;
September; break;
Oktober; break;
Nopember; break;
Desember;
}
return ( s1 + + s2 + + s3 );
}
public char getStatus()
{
return (status);
}
public char getInfoStatus()
{
String temp = "";
switch (status)
{
case 'B' : temp
case 'M' : temp
case 'D' : temp
case 'J' : temp
}
=
=
=
=
return (temp);
}
public boolean getJenisKelamin()
{
return (jenisKelamin);
}
public boolean getInfoJenisKelamin()
{
if (jenisKelamin)
return (Laki-laki);
else
return (Perempuan);
}
public void setNama (String n)
{
nama = n;
}
public void setDataLahir (short tanggal,
short bulan,
int tahun)
{
tanggalLahir = tanggal;
bulanLahir = bulan;
tahunLahir = tahun;
}
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
=
=
=
=
=
=
=
=
=
- 23 -
Untuk menguji class tersebut cobalah membuat program kecil seperti berikut ini:
Program 7.14
1
2
3
4
5
6
7
8
9
10
11
import modul.Penduduk;
public class UjiPenduduk
{
public static void main(String[] args)
{
Penduduk xyz = new Penduduk();
xyz.informasi();
}
}
Output program:
Coba anda ubah data-data variabel xyz tersebut lalu jalankan lagi programnya. Dengan terus berlatih insya
Allah anda akan semakin memahami metode OOP ini.
- 24 -
Penduduk
String nama
short tanggalLahir
short bulanLahir
int tahunLahir
char status
boolean jenisKelamin
String getNama()
String getDataLahir()
String getInfoDataLahir()
char getStatus()
String getInfoStatus()
boolean getJenisKelamin()
String getInfoJenisKelamin()
void setNama(String)
void setDataLahir(short,short,int)
void setStatus(char)
void setJenisKelamin(boolean)
void informasi()
Karyawan
String nip
short tanggalMasuk
short bulanMasuk
int tahunMasuk
String jabatan
String getNip()
String getMasukKerja()
String getInfoMasukKerja()
String getJabatan()
void setNip(String)
void setMasukKerja(short,short,int)
void setJabatan(String)
void informasi()
Program 7.15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package modul;
import modul.Penduduk;
//--------------------------// Definisi class Karyawan
//--------------------------public class Karyawan extends Penduduk
{
private String nip;
private short tanggalMasuk;
private short bulanMasuk;
private int tahunMasuk;
private String jabatan;
public Karyawan()
{
super();
nip = "000";
tanggalMasuk = 1;
bulanMasuk = 1;
tahunMasuk = 1990;
jabatan = "staff";
}
public String getNip()
{
- 25 -
29
30
31
32
33
34
return (nip);
}
public String getMasukKerja()
{
return ( Short.toString(tanggalMasuk) + '-' +
Short.toString(bulanMasuk) + '-' +
Integer.toString(tahunMasuk) );
}
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
}
}
Program 7.16
1
2
3
4
5
- 26 -
import modul.Karyawan;
public class UjiKaryawan
{
public static void main(String[] args)
6
7
8
9
10
11
{
Karyawan xyz = new Karyawan();
xyz.informasi();
}
}
Output program:
Method informasi() yang diwariskan oleh class Penduduk akan di-overwrite oleh class Karyawan, karena
cara menampilkan informasi maupun jumlah data yang harus diinformasikan berbeda pada kedua class
tersebut, namun class Karyawan boleh memanggil method informasi() dari class Penduduk pada salah satu
instruksinya, seperti tampak pada baris nomor 86.
- 27 -
Penduduk
String nama
dst
String getNama()
dst
Mahasiswa
String nim
short tanggalMasuk
short bulanMasuk
int tahunMasuk
String getNim()
String getMasukKuliah()
String getInfoMasukKuliah()
void setNim(String)
void setMasukKuliah(short,short,int)
void informasi()
Berikut ini adalah implementasi desain class Mahasiswa ke dalam kode Java.
Program 7.17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
- 28 -
package modul;
import modul.Penduduk;
//---------------------------// Definisi class Mahasiswa
//---------------------------public class Mahasiswa extends Penduduk
{
private String nim;
private short tanggalMasuk;
private short bulanMasuk;
private int tahunMasuk;
public Mahasiswa()
{
super();
nim = "000";
tanggalMasuk = 1;
bulanMasuk = 8;
tahunMasuk = 2003;
}
public String getNim()
{
return (nim);
}
public String getMasukKuliah()
{
return ( Short.toString(tanggalMasuk) + '-' +
Short.toString(bulanMasuk) + '-' +
Integer.toString(tahunMasuk) );
}
public String getInfoMasukKuliah()
{
String s1 = Short.toString(tanggalMasuk);
String s2 = "";
String s3 = Integer.toString(tahunMasuk);
switch (bulanMasuk)
{
case 1 : s2 = "Januari"; break;
case 2 : s2 = "Februari"; break;
case 3 : s2 = "Maret"; break;
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
case 4 : s2
case 5 : s2
case 6 : s2
case 7 : s2
case 8 : s2
case 9 : s2
case 10 : s2
case 11 : s2
case 12 : s2
"April"; break;
"Mei"; break;
"Juni"; break;
"Juli"; break;
"Agustus"; break;
"September"; break;
"Oktober"; break;
"Nopember"; break;
"Desember";
}
return ( s1 + ' ' + s2 + ' ' + s3 );
}
public void setNim (String nim)
{
this.nim = nim;
}
public void setMasukKuliah ( short tanggal,
short bulan,
int tahun )
{
tanggalMasuk = tanggal;
bulanMasuk = bulan;
tahunMasuk = tahun;
}
66
67
68
69
70
71
72
73
74
75
76
77
78
79
=
=
=
=
=
=
=
=
=
Secara keseluruhan, bagan 3 (tiga) class yang sudah kita buat ditunjukkan sebagai berikut:
Penduduk
String nama
dst
String getNama()
dst
Karyawan
Mahasiswa
String nip
String nim
dst
dst
String getNip()
String getNim()
dst
dst
- 29 -
tidak langsung juga memperoleh data warisan dari class Penduduk. Sebagai data tambahan kita hanya
menggunakan data ID yang menyatakan nomor identitas seorang anggota menwa di kesatuannya.
Secara bagan hirarki, keadaan class Menwa bisa digambar sebagai berikut:
Penduduk
String nama
dst
String getNama()
dst
Karyawan
Mahasiswa
String nip
dst
String nim
dst
String getNip()
dst
String getNim()
dst
Menwa
String id
String getId()
void setId(String)
void informasi()
Seperti class induk, sebuah class anak juga bisa diturunkan menjadi sejumlah class anak lagi secara tak
terbatas. Class yang berada di jenjang terbawah akan mendapat warisan sejumlah besar data dari seluruh
induknya tanpa harus melakukan pengetikan seluruh data tersebut. Ini sebabnya mengapa di awal bab
kami katakan bahwa metode OOP menawarkan suatu teknik pembuatan dan pengembangan program
aplikasi dengan cara yang mudah dan menyenangkan.
Program 7.18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
- 30 -
package modul;
import modul.Mahasiswa;
//-----------------------// Definisi class Menwa
//-----------------------public class Menwa extends Mahasiswa
{
private String id;
public Menwa()
{
super();
id = "000";
}
public String getId()
{
return (id);
}
public void setId (String id)
{
this.id = id;
}
public void informasi()
{
super.informasi();
32
33
34
35
Setelah seluruh class di-compile sesuai dengan urutan pembuatannya, maka anda akan melihat seluruh
file class di dalam sebuah directory modul. Berikut ini merupakan contoh tampilan directory modul di
komputer kami.
- 31 -
- 32 -