Kamis, 22 Desember 2011

TOSTRING

Setiap class pastin extends class Object, class Object memiliki 7 method setiap method mempunyai tujuan tertentu.
wait();
notify();
notifyAll();
finalize();
toString();
equals();
hashCode();

Method toString digunakan oleh java untuk mendapatkan representasi string dari object atau class. Implementasi default dari class object adalah mencetak nama class diikuti oleh alamat memory dari object tersebut.

public class ToStringTest{
           public static void main(String[] args){
                      ToStringTest test= new ToStringTest();
                       System.out.println("Implementasi toString dari class Object menghasilkan : " + test);
           }
}

ToStringTest@1e73498

String yang dikembalikan method toString tidak deskriptif, dapat di override method toString agar string yang dikembalikan lebih deskriptif.

public class ToStringOverrideTest{
            public String toString(){
                        return "Ini string dari class ToStringOverrideTest";
            }
            public void main (String[] args){
                       ToStringOverrideTest test = new ToStringOverrideTest();
                       System.out.println("Implementasi toString dari class Object menghasilkan : " + test);
            }
}

INTERFACE

Ketika mendeklarasikan class yang mengimplementasikan interface, menandatangani kontrak untuk mengimplementasikan semua method di dalam interface.

public interface PersonDao{
            void save(Person p);
            void delete(Person p);
            Person getById(long id);
}

Class PersonDaoImpl yang akan mengimplementasikan interface Person dao, maka semua method yang ada di interface PersonDao akan diimplementasikan juga

public class PersonDaoImpl implements PersonDao{
              public void save (Person p){
                          System.out.println("Menyimpan person");
              }
              public void delete (Person p){
                          System.out.println("Menghapus person");
             }
             public Person getById (Long id){
                          Person p = new Person();
                          p.setId(id);
                          p.setNama("abc");
                          return p;
             }
}

Cara agar tidak semua method dalam interface diimplementasikan pada class implementasinya dengan menggunakan keyword abstract pada deklarasi class, serta gunakan keyword abstract pada method yang tidak diimplementasikan.

public abstract class PersonDaoImpl implements PersonDao{
                public void save(Person p){
                          System.out.println("Menyimpan person");
                }
                public void delete(Person p){
                          System.out.println("Menghapus person");
                }
                public abstract Person getById(Long id)
}

Pada dasarnya interface adalah sebuah class yang dideklarasikan dengan keyword abstract dan semua method didalamnya bersifat public abstract, interface PersonDao statusnya setara seperti

public abstract class PersonDao{
            public abstract void save(Person p);
            public abstract void delete(Person p);
            public abstract Person getById(Long id);
}

Tetapi tetap saja interface dengan class adalah dua hal yang berbeda.
Interface sama hal nya dengan class dapat meng extends interface lain. Interface yang meng extends interface lain akan mempunyai semua method yang digunakan oleh class orang tuanya.

CASTING VARIABLE REFERENCE

Polimorfisme mengijinkan sebuah variable yang dideklarasikan menggunakan class orang tuanya diinisiasi dengan object menggunakan class anaknya. Bagaimana sebuah variable yang dideklarasikan menggunakan class orangtuanya diinisiasi dengan object menggunakan class anaknya akan diassign ke variable lain dengan tipe anaknya. Hal ini bisa dilakukan dengan menggunakan casting

Customer c = new MemberCustomer();
// casting berhasil karena c diinisiasi dengan class MemberCustomer
MemberCustomer mc = (MemberCustomer) c
c = new Customer();
// casting gagal dan terjadi ClassCastException karena c diinisiasikan dengan
// class Customer
mc = (MemberCustomer) c;
String s = "ini string";
// kode ini gagal dikompile karena String tidak ada hubungan sama sekali dengan
// class MemberCustomer
mc = (MemberCustomer) s;

Rabu, 21 Desember 2011

OVERRIDING DAN OVERLOADING

Setiap class meng extends class lain, class tersebut bisa meng overriding method yang ada di dalam class orang tuanya. Alasannya karena di class anak ingin mengimplementasikan method tersebut dengan cara yang berbeda. Misal dalam class MemberCustomer akan mengoverride method setId, untuk memeriksa apakan id yang dimasukkan null atau tidak, kalau null maka pesan akan di munculkan ke dalam console. Setelah pesan dicetak, method setId yang dipunyai oleh orang tua yang dipunyai oleh class Customer, hal ini bisa dilakukan dengan keyword super.

import java.io.Serializable;

public class MemberCustomer extends Customer implements Serializable{
            public void setId(Long aId){
                       if(aId ==  null){
                                  System.out.println("nilai id tidak boleh null");
                       }else {
                                 super.setId(aId);
                       }
            }
}

Overriding method dilakukan dengan cara mendeklarasikan method yang sama persis dengan method yang ada di class Orang Tuanya. Deklarasi method harus sama persis mulai dari access modifier, keyword yang digunakan, nama method, jumlah parameter, letak parameter, hingga deklarasi throws exception.

Apa yang terjadi jika mendeklarasikan sebuah variable dengan tipe Customer dan diinisiasi dengan object dari MemberCustomer, method setId milik siapa yang akan dieksekusi? Method yang dioverride akan terikat dengan instace dari variable bukan tipe dari variable, jadi yang akan dieksekusi adalah method dari MemberCustomer bukan dari Customer

public class OverridingTest{
          public static void main (String[] args){
                     Customer c = new Customer();
                     Customer mc = new MemberCustomer();
                     Long id = null;
                     // method yang dipanggil adalah yang dari class Customer karena c
                     // dideklarasikan dengan tipe Customer dan di inisiasi dengan class
                     // Customer
                     c.setId(id);

                     //method yang dipanggil adalah yang dari class MemberCustomer
                     // karena mc dideklarasi dengan tipe Customer dan diinisiasi dengan
                     // class MemberCustomer
                     mc.setId(id);

          }
}

Method overload merupakan feature dalam java dimana dua method dapat di deklarasikan dengan nama yang sama asalakan mempunyai argumen yang berbeda, baik dari jumlah tipe atau urutan parameternya

public void setId(Long aId){}
public void setId(Integer aId){}
public void setId(Long aId, boolean checkNull){}
public void setId(boolean checkNull, Long aId){}

Overriding dan Overloading juga berlaku pada constructor, karena pada dasarnya constructor adalah method.

POLIMORFISME (POLYMORPHISM)

Secara harfiah (makna kata) artinya banyak bentuk. Sebuah object dapat diassign kedalam tipe yang berbeda - beda. Contohnya MemberCustomer, MemberCustomer IS-A :
Object, karena semua class pasti extends Object
Customer, karena MemberCustomer turunan Customer
MemberCustomer

jadi kalau ada variable bertipe Object, Customer, MemberCustomer bisa diassign dengan instance dari MemberCustomer

Object o = new MemberCustomer();
Customer c = new MemberCustomer();
MemberCustomer mc = newMemberCustomer();

Object object = mc;
Customer cust = mc;

Interface juga bisa digunakan dalam skenario IS-A, misal class MemberCustomer juga bisa mengimplementasikan sebuah interface, kemudian interface ini bisa digunakan sebagai tipe variable yang bisa diassign dengan instace dari MemberCustomer.

public class MemberCustomer extends Customer implements Serializable {}

Sekarang kita bisa mendeklarasikan varible bertipe Serializable dengan mengassign instance dari MemberCustomer ke dalam variable tersebut, atau dengan kata lain MemberCustomer IS-A Serializable.

Serializable s = new MemberCustomer();

Jadi MemberCustomer mempunyai banyak bentuk.

INHERITANCE, IS-A, HAS-A

Inheritance (turunan) ada di mana-mana dalam Java. Sangat tidak mungkin membuat aplikasi tanpa melibatkan konsep Inheritance, faktanya setiap class yang kita tulis adalah turunan dari class Object. Anda ingin bukti? Ingat-ingat lagi bab tentang operator, di sana ada satu operator instanceof, operator ini digunakan untuk mengetes apakah sebuah object merupakan tipe dari suatu class. Operator ini akan mengembalikan true kalau tipe dari object tersebut adalah class yang ada di operand sebelah kanan dari operator instanceof, sebaliknya nilainya adalah false.

public class InheritanceTest{
            public static void main(String[] args){
                     InheritanceTest test = new InheritanceTest();
                     if (test instanceof Object ){
                               System.out.println("test tipenya Object");
                    } else {
                               System.out.println("test tipenya bukan Object");
                    }
           }
}

test tipenya Object

Terbukti bahwa walaupun tidak secara eksplisit kita defnisikan InheritanceTest sebagai turunan dari Object

Implementasi inheritance dalam kode menggunakan keyword extends. Kalau kita ingin membuat sebuah class turunan dari class yang lain, kita gunakan keyword extends setelah deklarasi nama class diikuti dengan class yang ingin digunakan sebagai orang tua dari class tersebut. Misalnya kita ingin akan membuat dua buah class, class pertama adalah Customer sedangkan class kedua adalah MemberCustomer, dimana class MemberCustomer adalah turunan dari class Customer. Kode class Customer adalah seperti di bawah ini

public class Customer{}

public class MemberCustomer extends Customer {}

Class MemberCustomer dalam hal ini mempunyai hubungan IS-A dengan class Customer. Kalimat lengkapnya adalah “MemberCustomer IS-A Customer”. Hal ini dikarenakan MemberCustomer adalah turunan Customer, analoginya kita bisa menggunakan kucing dan hewan. Kucing adalah turunan dari hewan, maka kucing adalah hewan. Sama juga seperti MemberCustomer adalah turunan dari Customer, maka MemberCustomer adalah Customer.

Apa tujuan dari inheritance dilihat dari sisi kode? Yang pertama adalah mempromosikan code reuse, yaitu penggunaan kembali kode yang sudah ditulis. Hal ini dikarenakan, sebagai turunan dari Customer, MemberCustomer akan mempunyai semua sifat-sifat (kode) dari class Customer. Misalnya kita ubah sedikit kode di atas, kita tambahkan property dan method di dalam class Customer :

public class Customer{

           private Long id;

           public Long getId(){
                     return id;
          }

          public void setId (Long aId){
                     this.id = aId;
         }

}

public class MemberCustomer extends Customer {}

public class CustomerTest {
          public static void main(String[] args) {
                  MemberCustomer member = new MemberCustomer();
                  member.setId(100l);
                  System.out.println("id customer : " + member.getId());
          }
}

id customer : 100

Terlihat bahwa tidak ada error dalam proses kompilasi, padahal class MemberCustomer tidak mendefnisikan apapun, tetapi method setId dan getId dapat digunakan. Hal ini dikarenakan MemberCustomer mengextends Customer, sehingga method setId dan getId diturunkan. Catat juga bahwa property id sendiri tidak diturunkan ke dalam MemberCustomer, karena property id menggunakan private sebagai access modifer.

Hubungan HAS-A lebih sederhana. Hubungan HAS-A atau komposisi (composition) terjadi kalau sebuah class mempunyai sebuah property. Misal kita dapat melihat Customer HAS-A Long dengan nama id.

Buat satu class dengan nama Adress, class ini digunakan oleh Customer untuk mendefinisikan alamat Customer

public class Address {
            private String street;
            private String city;
            private String postCode;
}

Hubungan antara class Customer dengan Address adalah HAS-A, diimplementasikan dengan membuat property dengan tipe Address pada class Customer.

public class Customer {
            private Long id;
            private Address address;

            public void setId (Long aId){
                       this.id = aId;
            }
           
            public Long getId(){
                       return this.id;
            }

            public void setAddress (Address aAddress){
                       this.address =  aAddress;
            }

            public Address getAdress(){
                        return this.address;
            }
}

Kode diatas memperlihatkan hubungan HAS-A antara Customer dengan Address

ENKAPSULASI

Enkapsulasi adalah konsep dimana sebuah logic kode dibungkus dalam satu bentuk kode yang menggambarkan dunia nyata. Class adalah sebuah enkapsulasi dari perilaku yang diwakilinya dalam dunia nyata. Setiap entitas dalam dunia nyata mempunyai karakteristik dan perilaku. Karakteristik diwujudkan sebagai property dan perilaku diwujudkan sebagai method. Kedua hal ini karakteristik dan perilaku dienkapsulasi menjadi satu entitas dalam class.

Bahasa prosedural tidak memiliki feature enkapsulasi ini, kalau kita melihat kode kita tidak bisa melihat wujud abstract kode tersebut dengan dunia nyata. Semua hanya fungsi / method data berceceran di sana / sini. OOP memberikan konsep yang praktis bagaimana menjembatani logic yang ada didunia nyata dengan wujudnya dalam kode. Misal kita berbicara tentang customer, kita berbicara tentang customer yang nyata juga berbicara tentang class Customer yang ada dalam kode.

Enkapsulasi menyebabkan kode menjadi self explaind, artinya hanya dengan melihat kode dapat mengetahui apa logic dibalik kode ini, atau kita bisa mengetahui apa maksud dari kode yang sedang kita baca.