Posting ini adalah lanjutan dari posting saya yang sebelumnya tentang :
Pada topik ini akan dibahas
- Specialization dan Generalization
- Inheritance
- Polymorphism
- Versioning
Specialization dan Generalization
Class dan instannya (objek) tidak berdiri sendiri, seperti objek manusia yang merupakan mahluk sosial tidak hanya berdiri sendiri, objek akan saling berelasi dan berinteraksi, demikian *** pada OOP.
Salah satu hubungan antar objek yang paling penting yang terjadi di dunia nyata adalah spesialisasi yang bisa didefinisikan sebagai is-a relationship, misal anjing adalah mamalia, jika anjing termasuk anggota mamalia maka dia memiliki ciri-ciri special khas yaitu menyusui, punya bulu. Selain sifat-sifat pada mamalia anjing juga memiliki ciri yang spesifik khas anjing yang tidak dipunyai anggota mamalia lainnya seperti kucing.
Relasi spesialisasi dan generalisasi terjadi pada contoh diatas, anjing dan kucing secara general merupakan anggota mamalia tetapi juga terspesialisasi secara spesifik sebagai anjing dan kucing yang mempunyai ciri khas yang berbeda. Relasi tersebut dapat digambarkan secara hirarki.
Misal gambar dibawah akan menunjukan hirarki antara class window, button, dan listbox
Gambar diatas menunjukan relasi antara window, button, dan listbox. Button dan listbox sama-sama memiliki karakteristik yang dimiliki oleh window, tetapi button dan listbox juga memiliki ciri-ciri spesifik khas mereka sendiri. Contoh lain yang lebih rinci untuk menggambarkan spesialisasi dan generalisasi dapat digambarkan sebagai berikut:
Inheritance
Pada C# hubungan spesialisasi diimplementasikan menggunakan prinsip inheritance. Penulisan inheritance di C# sebagai berikut
public class ListBox : Window
Kode diatas berarti class ListBox adalah turunan dari class Window
Penggunaan inheritance dapat dilihat pada program dibawah ini
1: public class Window { 2: //variabel dideklarasikan private sehingga tidak bisa diakses oleh kelas
3: //turunannya
4: private int top;
5: private int left;
6:
7: //objek konstruktor
8: public Window(int top, int left) { 9: this.top = top;
10: this.left = left;
11: }
12:
13: public void DrawWindow() { 14: Console.WriteLine("Draw window pada ({0},{1})", 15: top, left);
16: }
17: }
18:
19: public class ListBox : Window { 20: //member variable baru pada class anak
21: private string listBoxContent;
22: public ListBox(int top, int left, string contents):base(top,left) { 23: this.listBoxContent = contents;
24: }
25:
26: //versi baru karena override dari base classnya
27: public new void DrawWindow() { 28: base.DrawWindow();
29: Console.WriteLine("Menuliskan string pada listbox: {0}", 30: listBoxContent);
31: }
32: }
33:
34: class LatInheritance { 35: public static void Main(string[] args) { 36: Window objWindow = new Window(10, 15);
37: objWindow.DrawWindow();
38:
39: ListBox objList = new ListBox(15, 20, "Hello ListBox");
40: objList.DrawWindow();
41: }
42: }
Memanggil Base Class Constructor
Pada contoh diatas class ListBox adalah turunan dari class Window, class ListBox mempunyai konstruktornya sendiri yang memiliki tiga parameter, konstruktor pada class ListBox dapat menggunakan tanda : (titik dua) untuk memanggil kosntruktor base class-nya (konstruktor pada class Window)
public ListBox(int top, int left, string theContents):base(top, left)
Karena konstruktor tidak dapat diturunkan maka class turunan harus memiliki konstruktor sendiri.
Polymorphism
Ada dua aspek yang paling penting pada inheritance yang pertama adalah code reuse, sebagai contoh ketika anda membuat class ListBox maka anda dapat menggunakan logic yang sudah dibuat pada class Window
Aspek kedua yang tidak kalah penting dari inheritance adalah polymorhism, poly berarti banyak dan morph berarti bentuk, jadi polymorphism dapat berarti dapat menggunakan banyak bentuk tanpa harus mengacu details yang sama.
Dari istilahnya Polymorphism kesannya sulit dan kompleks, tetapi sebenarnya simple, ilustrasinya begini ketika sebuah perusahaan telpon / provide telpon mengirimkan signal ke anda (dering telpon), mereka tidak tahu telpon apa yang anda gunakan, bisa model lama dengan dering kuno, bisa HP dengan dering music mp3, TV Phone, PDA Phone dll. yang provider tahu bahwa masing-masing telepon mempunyai ‘base type’ telepon dan mempunyai method untuk berdering. Ketika provider mengirimkan signal mereka hanya berharap bahwa telepon akan berdering tidak peduli jenis telponnya, nah provider telepon memperlakukan telepon anda secara polymorphism.
Membuat Type Polymorphism
Dari gambar diatas dapat anda lihat, ListBox is-a Control (karena ListBox turunan dari Control), Button is-a Control, kita berharap bahwa dapat memperlakukan keduanya sebagai Control. Misal anda mempunyai banyak control di collection untuk digambar ke windows, dan mengharapkan ketika memanggil method draw() pada control maka control2 tersebut akan tergambar sesuai dengan tipe objectnya (mis: ListBox, RadioButton, Command, dll).
Anda dapat mengimplementasikan polymorphism dengan dua cara yaitu:
- Membuat virtual method pada base class (class induk)
- Membuat class turunan yang mempunyai method dengan keyword override yang mengganti isi dari method dengan keyword virtual yang ada pada base class-nya.
Penggunaan prinsip polymorphism dapat dilihat pada contoh program dibawah ini
1: public class Control { 2: //variabel dideklarasikan private sehingga tidak bisa diakses oleh kelas
3: //turunannya
4: private int top;
5: private int left;
6:
7: protected int Top { 8: get { 9: return this.top;
10: }
11: set { 12: this.top = value;
13: }
14: }
15:
16: protected int Left { 17: get { 18: return this.left;
19: }
20: set { 21: this.left = value;
22: }
23: }
24:
25: //objek konstruktor
26: public Control(int top, int left) { 27: Top = top;
28: Left = left;
29: }
30:
31: public virtual void DrawWindow() { 32: Console.WriteLine("Draw window pada ({0},{1})", 33: top, left);
34: }
35:
36: }
37:
38: public class ListBox : Control { 39: //member variable baru pada class anak
40: private string listBoxContent;
41: public ListBox(int top, int left, string contents)
42: : base(top, left) { 43: this.listBoxContent = contents;
44: }
45:
46: //versi baru karena override dari base classnya
47: public override void DrawWindow() { 48: base.DrawWindow();
49: Console.WriteLine("Menuliskan string pada listbox: {0}", 50: listBoxContent);
51: }
52:
53: }
54:
55: public class Button : Control { 56: public Button(int top, int left) : base(top, left) {} 57:
58: public override void DrawWindow() { 59: //base.DrawWindow();
60: Console.WriteLine("Menggambar button pada ({0},{1})", Top, Left); 61: }
62: }
63: class LatPolymophism { 64: static void Main(string[] args) { 65: Control win = new Control(10, 15);
66: ListBox lstBox = new ListBox(5, 10, "Text pada ListBox");
67: Button b = new Button(5, 6);
68: win.DrawWindow();
69: lstBox.DrawWindow();
70: b.DrawWindow();
71:
72: Control[] winArray = new Control[3];
73: winArray[0] = new Control(10, 15);
74: winArray[1] = new ListBox(5, 10, "Pada ListBox");
75: winArray[2] = new Button(5, 6);
76:
77: for (int i = 0; i < 3; i++) { 78: winArray.DrawWindow();
79: }
80: }
81: }
Dapat dilihat dari contoh diatas bahwa base class yaitu Window mempunyai method yang bernama DrawWindow() yang mempunyai keyword virtual, ini berarti method tersebut dapat di override atau diganti implementasinya dengan method yang nama dan parameternya sama persis di kelas turunannya yaitu class ListBox.
Versioning dengan new dan override keyword
Pada contoh diatas digunakan keyword virtual pada base class agar dapat dioverride oleh class turunannya. Akan timbul masalah jika misal: Perusahan A membuat class Control kemudian perusahaan B membelinya untuk membuat ListBox dan RadioButton (tapi B tidak bisa memodifikasi class Control karena hanya beli tanpa code), pada saat membuat ListBox perusahaan B menambahkan fungsi sort() kedalam class tersebut
1: public class ListBox : Control
2: { 3: public virtual void Sort( ) {...} 4: }
Hal diatas tidak menjadi masalah sampai perusahaan A menambahkan method sort() juga dalam class Control:
1: public class Control
2: { 3: // ...
4: public virtual void Sort( ) {...} 5: }
Maka akan menjadi rancu karena ada dua method dengan nama yang sama ketika anda akan memanggil method sort dari class turunan ListBox, tidak bisa dibedakan mana method sor() pada Control atau ListBox, untuk menangani masalah ini C# menyediakan keyword new.
1: public class ListBox : Control
2: { 3: public new virtual void Sort( ) {...} 4: }