Powered By Blogger

Rabu, 14 April 2010

Tugas PBO

Nama : Redi Purnama
Nim : 09530455
Kelas : TI 2A


Enkapsulasi, yang mencegah pengaksesan langsung ke fungsi atau variabel yang ingin dilindungi;

Inheritance, yang memungkinkan pendefinisian kelas baru yang diturunkan dari kelas yang sudah ada;

Polimorfisme, yang memungkinkan pengaksesan ke suatu metode bergantung dari tipe data objek yang diakses. Proses ini disebut juga dengan dynamic binding, yaitu penentuan alamat dari metode atau variabel yang akan diakses dilakukan pada saat run time.



Dari sini jelas bahwa PHP4 belum dapat dikategorikan sebagai bahasa yang mendukung OOP. Persyaratan enkapsulasi tidak dapat sepenuhnya diimplementasikan oleh PHP4, yang pada bahasa C++ atau Java direalisasikan dengan kata kunci private maupun protected. Pada PHP setiap atribut maupun metode masih dapat diakses langsung baik dari dari dalam kelas turunan, dari dalam kelas lainnya, maupun secara global.



Walaupun PHP4 tidak mengenal kata kunci abstract dan virtual seperti pada C++ maupun interface seperti pada Java, namun dukungan polimorfisme di PHP4 sudah diimplementasikan dengan cukup baik.



Faktor kekurangan lain seperti tidak adanya dukungan overloading metode (bukan overriding), tidak mengurangi pengguna PHP untuk menggunakan OOP dalam menulis program Web mereka, karena banyak faktor keuntungan yang dapat diperoleh seperti:

kemudahan dalam mengelola kode OOP;

kemudahan untuk memahami alur program;

dan tidak kalah pentingnya adalah kemudahan penggunaan kode yang sama untuk aplikasi lainnya.

Kelas dan Objek



Dalam konteks PHP, kelas dapat dibayangkan sebagai kumpulan dari variabel dan fungsi yang akan menangani variabel tersebut. Kelas juga dapat dipandang sebagai bentuk proses enkapsulasi, walau tidak sepenuhnya kriteria ini terpenuhi seperti yang telah diutarakan sebelumnya.



Dalam contoh aplikasi nanti, kita akan mengambil tema koneksi ke database MySQL dan PostgreSQL yang direalisasikan dalam bentuk OOP. Kelas MySQLDb dipakai sebagai kelas dasar yang akan digunakan oleh kelas PostgreSQL sebagai kelas turunan. Namun agar lebih mudah dimengerti, pada pembahasan awal kita akan menggunakan kelas sederhana yang tidak berhubungan dengan kedua kelas tadi.



Berikut ini adalah contoh penulisan sebuah kelas A:

class A {

// Pendeklarasian variabel

var $host_1;



// Konstruktor

function A() {

...

}



// Definisi metode MetodeB

function MetodeB($args="") {

...

}

}

Variabel Anggota



Variabel anggota (member variable) dideklarasikan dengan menggunakan kata kunci var diikuti dengan nama variabel. Namun penggunaan variabel anggota ini tanpa pendeklarasian sebelumnya tidak akan menyebabkan kesalahan pada PHP4. Variabel ini hanya boleh diinisialisasi dengan konstanta. Penginisialisasian dengan non-konstanta harus dilakukan di dalam konstruktor. Dalam OOP, terminologi lain untuk variabel anggota adalah properti atau atribut.

// Global variabel

$gHost = "172.20.172.10";



// Class

class A {

// Benar, inisialisasi dengan konstanta

var $host_1="localhost";

// Deklarasi variabel host_2

var $host_2;



// Konstruktor

function A() {

global $gHost;



// Benar, inisialisasi dengan non-konstanta

$this->host_2=$gHost;



// Benar, definisi variabel baru dari class

$this->host_3="192.168.0.0";

}

}

Tentang Metode



Cara mendefinisikan sebuah metode sama seperti pada fungsi. Hanya saja, proses ini harus dilakukan dalam lingkup kelas yang bersangkutan. Metode MetodeB() adalah salah satu metode yang didefinisikan pada kelas A.



Pada PHP4 tidak dikenal istilah overloading metode, yaitu pendefinisian beberapa metode berbeda yang mempunyai nama sama namun memiliki daftar argumen yang berbeda. Dalam PHP4 setiap metode harus memiliki nama berbeda. Walau begitu, PHP4 mengenal terminologi argumen default untuk fungsi atau metode. Di sini jumlah dan tipe data dari argumen yang digunakan pada pemanggilan metode dapat berbeda.

...

class A {

...

// Metode B

function MetodeB($args="") {

...

}

}

...



Metode MetodeB() mempunyai argumen default string kosong jika dipanggil tanpa argumen. Dua kemungkinan untuk memanggil metode ini dengan benar adalah sebagai berikut:

ObjekA = new A;

ObjekA->MetodeB();



atau

ObjekA->MetodeB("localhost");



Pada penulisan program memakai gaya OOP, sangat disarankan untuk tidak mengakses atribut secara langsung, melainkan melalui metode. Di sini umumnya dipakai awalan Set untuk memberikan nilai yang baru sebuah variabel. Sedang untuk mengakses nilai atribut digunakan awalan Get.

function SetHost($host) {

$this->host_1 = $host;

}



function GetHost() {

return $this->host_1;

}



Cara ini berhubungan erat dengan prinsip enkapsulasi, yang pada PHP4 belum didukung sepenuhnya, sehingga secara tidak langsung menghilangkan keuntungan cara penulisan metode seperti di atas, karena tidak ada cara untuk melindungi atribut dari pengaksesan secara langsung.

Konstruktor dan Destruktor



PHP4 juga mengenal konstruktor yang dideklarasikan dengan memakai metode yang memiliki nama sama dengan nama kelas yang mendefinisikannya. Konstruktor ini akan dipanggil pada pembuatan sebuah objek dari kelas yang bersangkutan. Ada sedikit perbedaan antara PHP3 dan PHP4 dalam proses pemanggilan konstruktor—terutama pada kelas turunan—yang akan diterangkan di bagian akhir artikel.



Dalam contoh sebelumnya, metode A() adalah konstruktor dari kelas A. Di sini biasanya dilakukan inisialisasi terhadap variabel dengan nilai non-konstanta.



PHP tidak mengenal destruktor. Jika memang diinginkan, dapat digunakan fungsi PHP register_shutdown_function() yang akan dipanggil jika skrip PHP selesai dikerjakan.

Pembuatan Objek



Untuk dapat menggunakan kelas yang telah didefinisikan, kita perlu membuat instan dari kelas tersebut. Proses ini dapat dilakukan dengan bantuan operator new yang akan menghasilkan sebuah objek dari kelas bersangkutan. Dengan operator ini kita dapat membuat beberapa objek dari kelas yang sama. Karena objek adalah individu kelas, maka objek ini tidak mempunyai ketergantungan terhadap objek yang lain.



Setelah kita mempunyai sebuah objek, maka kita dapat mengakses variabel anggota maupun metode yang dimiliki kelas tersebut dengan bantuan operator ->.

// Pembuatan objek baru

ObjekA = new A;



// Pemanggilan metode MetodeB

ObjekA->MetodeB();

Cara Pengaksesan



Pengaksesan ke metode atau ke variabel di dalam lingkup kelas itu sendiri dilakukan dengan bantuan operator $this->. Sebagai contoh, untuk mengubah variabel $host_1 dalam metode MetodeB(), dapat dilakukan dengan $this->host_1 = "localhost".

Inheritance dengan extends



Seperti telah disinggung sebelumnya, inheritance adalah proses pembuatan sebuah kelas yang diturunkan dari kelas lain yang sudah didefinisikan sebelumnya. Salah satu faktor keuntungannya adalah, kita hanya tinggal menambahkan atribut atau metode yang dibutuhkan dalam kelas baru yang akan kita buat. Terminologi kelas yang dijadikan dasar pembuatan kelas baru ini adalah kelas dasar (base class) atau kelas induk (parent class). Sedang kelas yang baru disebut juga kelas turunan (extended class) atau kelas anak (child class).



Pembuatan kelas turunan di PHP4 dapat dilakukan dengan operator extends. Namun harus diingat bahwa dalam PHP4 hanya diperbolehkan menggunakan satu kelas dasar. Penurunan dari beberapa kelas (multiple inheritance) tidak diperbolehkan.



Hal yang juga penting di sini adalah pemanggilan konstruktor kelas turunan. Pada PHP4, jika konstruktor kelas turunan tidak didefinisikan, maka otomatis konstruktor kelas dasar yang akan dipanggil, jika ada. Sedangkan pada PHP3, jika konstruktor kelas turunan tidak ada, konstruktor kelas dasar tidak akan dipanggil.



Berikut ini ilustrasi cara pembuatan kelas turunan dan pemanggilan konstruktor:

// Kelas dasar

class A {

function A() {

echo "Konstruktor class A.
\n";

}

}



// Kelas turunan

class B extends A {

}



$ObjekB = new B;



Kelas B yang tidak mempunyai konstruktor diturunkan dari kelas A yang mempunyai konstruktor. Seperti diharapkan, pada pembuatan objek dari kelas B, maka konstruktor kelas A akan dipanggil. Program di atas akan menampilkan keluaran:

Konstruktor kelas A.



Dalam manual PHP4 dikatakan, jika kelas turunan tidak mempunyai konstruktor, maka konstruktor dari kelas dasar, yaitu metode yang mempunyai nama sama dengan nama kelas dasar, akan dipanggil. Namun pada PHP versi 4.0.4 maupun 4.0.5 hal ini belum dilakukan. Kita akan melihat kasus berikut.



Sekarang jika kita menambahkan sebuah metode di kelas A dengan nama B() (sengaja namanya sama dengan nama kelas B), dan kita jalankan lagi program di atas, maka yang keluar tidak seperti yang kita harapkan.

class A {

...

// Metode tambahan

function B() {

echo "Metode normal B.
\n";

}

}



Tampilan yang dikeluarkan adalah seperti berikut:

Metode normal B.



Di sini tiba-tiba metode B() di kelas A menjadi konstruktor dari kelas B yang akan dipanggil secara otomatis pada setiap pembuatan objek baru dari kelas A. Hal ini seharusnya hanya ditemui pada PHP3, dan tidak pada PHP4 seperti informasi di manual. Kemungkinan besar versi yang sekarang ada masih mengandung kesalahan.



Kelas turunan dapat melakukan overriding metode dari kelas dasar. Jika metode di kelas dasar yang sudah dioverride ini hendak dipanggil dari kelas turunan, maka dapat digunakan operator ::. Operator ini juga dapat dipakai dari lingkup global untuk memanggil metode dari suatu kelas tanpa membuat objek terlebih dahulu.

class A {

function hallo() {

echo "Metode hallo dari class A.
\n";

}

}



class B extends A {

// Override metode hallo dari class A

function hallo() {

echo "Metode hallo dari class B.
\n";

// Memanggil metode hallo di class A

A::hallo(); // Atau dapat juga parent::hallo()

}

}



// Memanggil metode tanpa objek

A::hallo();



$ObjekB = new B;

$ObjekB->hallo();



Program di atas akan menampilkan keluaran seperti berikut:

Metode hallo dari class A.

Metode hallo dari class B.

Metode hallo dari class A.



Untuk mengakses variabel anggota atau metode di kelas dasar tanpa harus tahu nama kelasnya, dapat digunakan kata kunci parent. Pada contoh di atas, jika baris A::hallo() diganti dengan parent::hallo() maka hasilnya akan identik.

Polimorfisme



Seperti dituliskan sebelumnya, polimorfisme adalah cara yang memungkinkan pengaksesan ke suatu metode bergantung dari tipe data objek yang diakses, termasuk dari metode di kelas dasar. Untuk memperjelasnya, mari kita lihat contoh berikut. Di sini kita akan membuat satu kelas dasar, Bangun2D dan dua kelas turunan, Lingkaran dan PersegiPanjang.

class Bangun2D {

function Luas() {}

function Keliling() {}

function Info() {

echo "Luas = ", $this->Luas(), ", Keliling = ", $this->Keliling();

echo “
\n";

}

}



class Lingkaran extends Bangun2D {

var $r;

function Lingkaran($r) { $this->r = $r; }

function Luas() { return pi()*$this->r*$this->r; }

function Keliling() { return 2*pi()*$this->r; }

}



class PersegiPanjang extends Bangun2D {

var $p;

var $l;

function PersegiPanjang($p, $l) { $this->p = $p; $this->l = $l; }

function Luas() { return $this->p*$this->l; }

function Keliling() { return 2*($this->p+$this->l); }

}



$bangun[] = new Lingkaran(10);

$bangun[] = new PersegiPanjang(6, 8);



foreach ($bangun as $b) {

$b->Info();

}



Program di atas akan menampilkan keluaran seperti berikut:

Luas = 314.15926535898, Keliling = 62.831853071796

Luas = 48, Keliling = 28



Dari contoh ini dapat dilihat, metode Info() kelas dasar Bangun2D tidak perlu mengetahui di kelas turunan mana ia sedang berada untuk mengetahui bagaimana cara menghitung luas dan keliling bangun. Jika metode ini dipanggil dari sebuah objek persegipanjang, maka Luas() dan Keliling() dari kelas Persegipanjang yang akan dipanggil; jika objek sebuah lingkaran, maka luas dan keliling lingkaran yang dihitung. Keuntungannya, jika suatu saat kita menambah bangun khusus lain, katakanlah Segitiga atau Poligon, maka metode Info() kelas Bangun2D tidak perlu diubah. Dengan kata lain, metode Info() menjadi reusable. Atau, bisa dikatakan juga bahwa OO dan polimorfisme mengizinkan kode lama (kelas Bangun2D) dapat memanggil kode baru (kelas Segitiga atau Poligon di masa depan).

Kelas MySQLDb dan PostgreSQLDb



Setelah kita belajar teori Pemrograman Berorientasi Objek dengan PHP, maka kita akan melihat penggunaannya dalam aplikasi yang nyata. Dalam CD majalah Anda akan menemukan file oop_php.tgz. Di dalamnya berisi antara lain file mysql.class.php yang mengimplementasikan kelas MySQLDb dan psql.class.php yang mengimplementasikan kelas PostgreSQLDb.



Kelas MySQLDb adalah kelas dasar yang mempunyai metode untuk melakukan operasi ke server database MySQL dengan instruksi sesederhana mungkin dalam pekerjaan yang kompleks. Sebuah objek dari kelas ini dapat melakukan operasi berulang kali, tanpa kehilangan informasi atau data dari operasi sebelumnya. Hal ini sangat bermanfaat terutama ketika melakukan query select.



Kelas PostgreSQLDb sebagai kelas turunan mempunyai fitur yang sama dengan kelas induknya MySQLDb.



Hubungan antara kedua kelas dalam contoh kita kali ini barangkali bukan teladan model abstraksi yang optimal. Dalam aplikasi abstraksi database yang lebih umum, biasanya dibuat satu kelas dasar abstrak yang mendefinisikan interface yang seragam, lalu dibuat kelas-kelas turunan sebagai driver untuk masing-masing jenis database. Jadi biasanya kelas MySQL dan PostgreSQL letaknya sederajat satu sama lain, di bawah satu kelas induk. Contohnya adalah di Perl dengan DBI sebagai kelas induk dan DBD::mysql serta DBD::Pg sebagai kelas-kelas driver. Namun demi kesederhanaan contoh, kita hanya akan membuat dua kelas seperti telah disebutkan sebelumnya.

Konstruktor MySQLDb



Kebanyakan aplikasi PHP mempunyai sebuah file konfigurasi yang berisikan banyak variabel global yang dibutuhkan oleh file lainnya. Pengguna aplikasi biasanya cukup mengedit file ini untuk menyesuaikan aplikasi di sistem yang ada.



Demikian juga kelas MySQLDb dapat dikonfigurasi baik lewat daftar argumen maupun lewat variabel global di mana daftar argumen mempunyai prioritas lebih tinggi. Proses konfigurasi ini dilakukan oleh konstruktor.

class MySQLDb {

...

function MySQLDb($args="") {

global $cfgDBHost, $cfgDBPort, $cfgDBUser, $cfgDBPasswd;



$this->dbh = false;



if (isset($args["host"]))

$this->host=$args["host"];

else

$this->host=$cfgDBHost;



if (isset($args["port"]))

$this->port=$args["port"];

else

$this->port=$cfgDBPort;



if (isset($args["user"]))

$this->user=$args["user"];

else

$this->user=$cfgDBUser;



if (isset($args["passwd"]))

$this->passwd=$args["passwd"];

else

$this->passwd=$cfgDBPasswd;



$this->rownr=0;

}

Metode Select()



Sebagian besar operasi ke database adalah query select. Metode Select() dalam kelas MySQLDb yang menangani operasi ini diimplementasikan sedemikian rupa, sehingga hasilnya disimpan dalam sebuah array yang sekaligus digunakan sebagai nilai kembali oleh metode ini. Dengan demikian data hasil query dapat diakses langsung tanpa harus melewati objek lagi.

function Select($string) {

$this->rowcount=0;

$result = mysql_query($string, $this->dbh);

$this->error=mysql_error();

if (empty($this->error)){

$entry = array();

$this->rowcount=mysql_num_rows($result);

$i=0;

while($row=mysql_fetch_array($result)){

$entry[$i] = $row;

$i++;

}

mysql_free_result($result);

}

return $entry;

}

Kelas PostgreSQLDb



Kelas PostgreSQLDb diturunkan dari kelas MySQLDb. Karena proses pengkonfigurasian sama seperti pada MySQL, maka konstruktor kelas ini hanya memanggil konstruktor dari base kelasnya.

class PostgreSQLDb extends MySQLDb {



function PstgreSQLDb($args="") {

parent::MySQLDb($args);

}

...

}



Jika kelas PostgreSQLDb ini tidak diturunkan dari kelas MySQLDb maka kita harus menulis lagi konstruktor yang sama seperti pada konstruktor MySQLDb.



Untuk mengetahui metode lainnya, pembaca dapat melihat langsung source code dari kedua kelas tersebut.

Contoh Aplikasi



Di sini akan diberikan satu aplikasi sederhana yang melakukan query ke database MySQL atau PostgreSQL, dan menampilkan hasilnya ke browser. Variabel yang diperlukan dalam proses koneksi ke server database disimpan dalam file konfigurasi config.inc.php yang akan digunakan oleh konstruktor kelas dasar MySQLDb.



Setelah mengedit variabel global yang harus disesuaikan dengan sistem yang Anda pakai, maka untuk memilih kelas mana yang akan digunakan, pengguna cukup menuliskan nama kelas yang dilewatkan sebagai parameter fungsi page_open() yang diimplementasi dalam file page.inc.php.

// Menggunakan kelas MySQLDb

if (!page_open(array("db" => 1,

"dbkelas" => "MySQLDb",

"page" => $PHP_SELF)))

die;



Jika ingin menggunakan kelas PostgreSQLDb maka Anda tinggal mengganti parameter "dbkelas"=>"MySQLDb" dengan "dbkelas"=>"PostgreSQLDb".



Pembuatan objek dari kelas sendiri akan ditangani oleh fungsi page_open(). Pada PHP hal ini dimungkinkan karena kelas juga dapat disimpan dalam variabel seperti kita lihat di bawah ini:

function page_open($args) {

global $cfgDatabase,$gDb;



// Menggunakan database ?

if (isset($args["db"])){

// Kelas database ada di argumen?

if (isset($args["dbclass"]))

$gDb = new $args["dbclass"];

// Memakai default

else

$gDb = new MySQLDb;



return $gDb->Connect();

}

return true;

}



Variabel global $gDb adalah objek kelas yang namanya tersimpan dalam $args["dbkelas"].



Dalam CD ada dua jenis file yang digunakan sebagai contoh aplikasi, yaitu mysql.php yang menggunakan kelas MySQLDb dan file postgres.php yang menggunakan kelas PostgreSQLDb untuk mengambil entri data dari tabel users. Gambar 1 dan 2 menunjukkan hasil tampilan keduanya.




Enkapsulasi Java

Enkapsulasi adalah suatu cara untuk menyembunyikan informasi detail dari suatu class. Dua hal yang mendasar dalam enkapsulasi yakni :

• Information hiding.

• Interface to access data.

Information hiding

Sebelumnya kita dapat mengakses anggota class baik berupa atribut maupun method secara langsung dengan menggunakan objek yang telah kita buat. Hal ini dikarenakan akses kontrol yang diberikan kepada atribut maupun method yang ada di dalam class tersebut adalah 'public'. Kita dapat menyembunyikan informasi dari suatu class sehingga anggota class tersebut tidak dapat diakses dari luar, caranya adalah hanya dengan memberikan akses kontrol 'private' ketika mendeklarasikan atribut atau method. Proses ini disebut dengan information hiding.

Interface to access data

Jika kita telah melakukan information hiding terhadap suatu atribut pada suatu class, lalu bagaimana cara melakukan perubahan terhadap atribut yang kita sembunyikan tersebut, caranya adalah dengan membuat suatu interface berupa method untuk menginisialisasi atau merubah nilai dari suatu atribut tersebut.



Implementasi UML

Berikut ini kita akan coba untuk lebih memahami penggunaan konsep enkapsulasi dengan mengimplementasikan UML berikut :



UML Vehicle class with no hiding

Vehicle class berisi atribut yang mempunyai modifier public(+), sehingga TestVehicle1 sebagai test program mempunyai akses langsung terhadap atribut pada Vehicle.

Listing program - Vehicle.java

public class Vehicle{

public double load, maxLoad;

public Vehicle (double maxLoad){

maxLoad = maxLoad + load;

}

public double getLoad(){

return load;

}

public double getMaxLoad(){

return maxLoad;

}

}

Listing program - TestVehicle.java

public class TestVehicle{

public static void main(String[] args){

System.out.println("Creating a vehicle with a 10,000kg maximum load.");

Vehicle vehicle = new Vehicle(10000.0);

System.out.println("Add box #1 (500kg)");

vehicle.load = vehicle.load + 500.0;

System.out.println("Add box #2 (250kg)");

vehicle.load = vehicle.load + 250.0;

System.out.println("Add box #3 (5000kg)");

vehicle.load = vehicle.load + 5000.0;

System.out.println("Add box #4 (4000kg)");

vehicle.load = vehicle.load + 4000.0;

System.out.println("Add box #4 (300kg)");

vehicle.load = vehicle.load + 300.0;

System.out.println("Vehicle load is = " +vehicle.getLoad() + "kg");

}

}

Compile Vehicle.java dan TestVehicle.java lalu jalankan TestVehicle.java. Seharusnya akan keluar tampilan sebagai berikut :




Analisa program

Kita lihat bahwa pada output program tersebut kita menginisialisasi batas maximum load 10,000 kg,

Vehicle vehicle = new Vehicle(10000.0);

akan tetapi dengan memberikan akses kontrol / modifier public pada atribut class Vehicle

public double load, maxLoad;

kita dapat mengakses langsung atribut class yang seharusnya perlu diberi pengecekan agar tidak sampai melebihi maxload

vehicle.load = vehicle.load + 500.0;

maka dapat mengakibatkan masalah(trouble) yakni batas maximum load yang kita buat tidak berpengaruh apapun sehingga terdapat penambahan boxes yang melebihi kapasitas(10050.0kg) dikaernakan tidak ada pengecekan kapasitas maksismum.




Vehicle class berisi atribut yang mempunyai modi_er public, sehingga TestVehicle1 sebagai test program mempunyai akses langsung terhadap atribut pada Vehicle.

Listing program - Vehicle.java

public class Vehicle1{

private double load, maxLoad;

public Vehicle1 (double max){

this.maxLoad = max;

}

public double getLoad(){

return this.load;

}

public double getMaxLoad(){

return this.maxLoad;

}

public boolean addBox(double weight){

double temp = 0.0D;

temp = this.load + weight;

if(temp <= maxLoad){

this.load = this.load + weight;

return true;

}

else{

return false;

}

}

}

Listing program - TestVehicle.java

public class TestVehicle1{

public static void main(String[] args){

System.out.println("Creating a vehicle with a 10,000 kg maximum load.");

Vehicle1 vehicle = new Vehicle1(10000);

System.out.println("Add box #1 (500kg) : " + vehicle.addBox(500));

System.out.println("Add box #2 (250kg) : " + vehicle.addBox(250));

System.out.println("Add box #3 (5000kg) : " + vehicle.addBox(5000));

System.out.println("Add box #4 (4000kg) : " + vehicle.addBox(4000));

System.out.println("Add box #5 (300kg) : " + vehicle.addBox(300));

System.out.println("Vehicle load is " +vehicle.getLoad() + "kg");

}

}

Compile Vehicle1.java dan TestVehicle1.java lalu jalankan TestVehicle1.java. Maka akan keluar tampilan sebagai berikut :










Analisa program

Kita lihat bahwa pada output program tersebut pada penambahan box ke-5 terjadi kelebihan kapasitas maksimal sehingga method addBox mengembalikan nilai false, dalam arti bahwa terjadi penolakan terhadap penambahan box ke 5.

Tidak ada komentar:

Posting Komentar