Pada Turtorial keempat ini akan dibahas beberapa topik yaitu:
- Abstract Class
- Sealed Class
- “Object” akar dari semua class
- Boxing dan Unboxing Types
- Interfaces
Abstract Class
Setiap tipe Window pasti mempunyai bentuk tampilan yang berbeda misal combobox, listbox, button, dll. Berarti setiap class turunan dari Window harus mempunyai method DrawWindow() nya sendiri yang berbeda satu sama lain. Untuk memastikan bahwa setiap class turunan harus mempunyai method tertentu maka anda harus mendefinisikan class tersebut sebagai abstract class dan memiliki method abstract.
Abstract method tidak mempunyai implementation, abstract method hanya semacam kontrak yang harus dipenuhi. Semua class yang diturunkan dari class yang mempunyai abstract method harus mengimplementasikan method tersebut.
Class yang didefinisikan sebagai abstract class tidak dapat dibuat instan class / objek, class yang didefinisikan abstract hanya dapat digunakan dengan cara diturunkan.
1: //mendeklarasikan abstract class
2: public abstract class Window
3: {
4: //konstruktor
5: public Window(int top, int left)
6: {
7: this.top = top;
8: this.left = left;
9: }
10:
11: //method abstract
12: public abstract void DrawWindow();
13:
14: protected int top;
15: protected int left;
16: } // end class Window
17:
18: // ListBox diturunkan dari Window
19: public class ListBox : Window
20: {
21: // konstruktor
22: public ListBox(int top, int left, string contents)
23: : base(top, left) // memanggil konstruktor dari base class
24: {
25: listBoxContents = contents;
26: }
27:
28: //implementasi method abstract pada class anak
29: public override void DrawWindow()
30: {
31: Console.WriteLine("Writing string to the listbox: {0}",
32: listBoxContents);
33: }
34: private string listBoxContents; // member variable yang baru
35: } // end class ListBox
36:
37: public class Button : Window
38: {
39: public Button(
40: int top,
41: int left)
42: : base(top, left) { }
43:
44: // implementasi abstract method
45: public override void DrawWindow()
46: {
47: Console.WriteLine("Drawing a button at {0}, {1}\n",
48: top, left);
49: }
50: } // end class Button
51:
52: public class Tester
53: {
54: static void Main()
55: {
56: Window[] winArray = new Window[3];
57: winArray[0] = new ListBox(1, 2, "First List Box");
58: winArray[1] = new ListBox(3, 4, "Second List Box");
59: winArray[2] = new Button(5, 6);
60:
61: for (int i = 0; i < 3; i++)
62: {
63: winArray[i].DrawWindow();
64: } // end for loop
65: } // end main
66: } // end class Tester
Sealed Class
Ini merupakan kebalikan dari abstract class, jika sebuah class dideklarasikan sebagai sebagai sealed class maka class tersebut tidak dapat diturunkan.
Object Root dari semua class
Semua class dari semua type diturunkan dari satu class untama yaitu class object. Meskipun tidak dituliskan secara eksplisit namun pada dasarnya semua class diturunkan dari class object.
Beberapa method yang ada pada class object adalah:
Method dari class yang ada diatas dapat dioverride oleh semua class karena pada dasarnya semua class diturunkan dari class object.
1: public class Dog
2: {
3: private int weight;
4:
5: // konstruktor
6: public Dog(int weight)
7: {
8: this.weight = weight;
9: }
10:
11: // override dari Object.ToString
12: public override string ToString()
13: {
14: return weight.ToString();
15: }
16: }
17:
18: public class Tester
19: {
20: static void Main()
21: {
22: int i = 5;
23: Console.WriteLine("The value of i is: {0}", i.ToString());
24:
25: Dog milo = new Dog(62);
26: Console.WriteLine("My dog Milo weighs {0} pounds", milo);
27: }
28: }
Boxing dan Unboxing Types
Boxing dan Unboxing adalah suatu proses ketika suatu tipe data value (seperti int) di konversikan menjadi tipe reference / object. Istilah boxing berarti diubah menjadi object dan unboxing berarti dikembalikan lagi ke tipe data value.
Proses boxing dilakukan secara implisit jadi compiler otomatis akan melakukannya ketika kita mengisi nilai bertipe value kedalam variabel bertipe object.
1: int myIntegerValue = 5;
2: object myObject = myIntegerValue; // cast to an object
3: myObject.ToString();
Tidak seperti boxing, proses unboxing harus eksplisit. Ketika proses unbox kita harus tahu tipe data apa yang kita ingin konversikan dari tipe objek-nya.
1: int myIntegerVariable = 123;
2:
3: //Boxing
4: object myObjectVariable = myIntegerVariable;
5: Console.WriteLine( "myObjectVariable: {0}",
6: myObjectVariable.ToString( ) );
7:
8: // unboxing (harus explicit)
9: int anotherIntegerVariable = (int)myObjectVariable;
10: Console.WriteLine( "anotherIntegerVariable: {0}",
11: anotherIntegerVariable );
12:
13: Output:
14: myObjectVariable: 123
15: anotherIntegerVariable: 123
Menghindari Boxing dengan Generic
Proses boxing dan unboxing mempengaruhi performa program, karena semua harus di boxing kedalam tipe object (misal: dalam penggunaan ArrayList). Pada C# 2.0 keatas sudah mendukung generic sehingga proses boxing dan unboxing dapat dihindari.
Interfaces
Jika anda ingin mendefinisikan tipe baru tetapi tidak ingin mengimplementasikan isinya secara langsung maka anda dapat menggunakan interfaces.
Pada dasarnya interface adalah sebuah kontrak, ketika anda mendesign interface seolah-olah anda mengatakan “jika anda ingin menggunakan fasilitas ini maka anda harus mengimplementasi method, dan property-nya”. Class yang menggunakan interface tersebut setuju dengan kontrak dan mengimplementasikan requirement yang ditentukan.
Perbedaan Interface dan Abstract Class
Programmer sering merasa bingung dalam mebedakan Interface dan Abstract Class. Beberapa perbedaannya adalah:
- Cara penggunaan Abstract Class adalah diturunkan, sedangkan cara penggunaan Interface adalah diimplementasikan.
- Pada C# lambang untuk menurunkan class dan menggunakan interfaces sama-sama menggunakan tanda “:” (titik dua). Tetapi untuk membedakan biasanya nama interface diawali dengan huruf I di depan misal: IEnumerable, IDisposable, dll.
- Sebuah class hanya dapat diturunkan dari satu abstract class tapi dapat menggunakan lebih dari satu interfaces.
- Method dan member variable pada abstract class boleh sudah ada isinya, sedangkan pada interfaces semua belum ada implementasinya.
- Pada Abstract Class semua method / member variable yang abstract harus diimplementasikan di class turunannya.
- Pada Interface semua member variable dan method harus diimplementasikan di class yang menggunakan interface tersebut.
- Access Modifier pada method dan member variable di Interface secara implisit adalah public.
1: //deklarasi interface
2: interface IStorable
3: {
4: void Read();
5: void Write(object obj);
6: int Status { get; set; }
7:
8: }
9:
10: public class Document : IStorable
11: {
12: // implementasi dari member variabel yang dideklarasikan di interface
13: private int status = 0;
14:
15: public Document(string s)
16: {
17: Console.WriteLine("Creating document with: {0}", s);
18: }
19:
20:
21: //implementasi method yang ada pada interface
22: public void Read()
23: {
24: Console.WriteLine(
25: "Implementing the Read Method for IStorable");
26: }
27:
28: public void Write(object o)
29: {
30: Console.WriteLine(
31: "Implementing the Write Method for IStorable");
32: }
33:
34: public int Status
35: {
36: get { return status; }
37: set { status = value; }
38: }
39:
40:
41: }
42:
43: class Tester
44: {
45: public void Run()
46: {
47: Document doc = new Document("Test Document");
48: doc.Status = -1;
49: doc.Read();
50: Console.WriteLine("Document Status: {0}", doc.Status);
51: }
52:
53: static void Main()
54: {
55: Tester t = new Tester();
56: t.Run();
57: }
58: }
59:
60: Output:
61: Creating document with: Test Document
62: Implementing the Read Method for IStorable
63: Document Status: -1
Mengimplementasikan lebih dari satu Interface
Pada C# sebuah class hanya dapat diturunkan dari sebuah class saja, tidak seperti bahasa C++ yang mendukung multipe inheritance. Tetapi untuk interface anda dapat tidak menggunakannya, menggunakan satu interface saja, atau menggunakan lebih dari satu interface.
1: interface IStorable
2: {
3: void Read();
4: void Write(object obj);
5: int Status { get; set; }
6:
7: }
8:
9: // lebih dari satu interface
10: interface ICompressible
11: {
12: void Compress();
13: void Decompress();
14: }
15:
16:
17: public class Document : IStorable, ICompressible
18: {
19: private int status = 0;
20:
21: public Document(string s)
22: {
23: Console.WriteLine("Creating document with: {0}", s);
24: }
25:
26: #region IStorable
27:
28: public void Read()
29: {
30: Console.WriteLine(
31: "Implementing the Read Method for IStorable");
32: }
33:
34: public void Write(object o)
35: {
36: Console.WriteLine(
37: "Implementing the Write Method for IStorable");
38: }
39:
40: public int Status
41: {
42: get { return status; }
43: set { status = value; }
44: }
45:
46: #endregion // IStorable
47:
48: #region ICompressible
49:
50: public void Compress()
51: {
52: Console.WriteLine("Implementing Compress");
53: }
54:
55: public void Decompress()
56: {
57: Console.WriteLine("Implementing Decompress");
58: }
59:
60: #endregion // ICompressible
61: }
62:
63:
64: class Tester
65: {
66: public void Run()
67: {
68: Document doc = new Document("Test Document");
69: doc.Status = -1;
70: doc.Read(); // dipanggil dari method IStorable
71: doc.Compress(); // dipanggil dari method ICompressible
72: Console.WriteLine("Document Status: {0}", doc.Status);
73: }
74:
75: static void Main()
76: {
77: Tester t = new Tester();
78: t.Run();
79: }
80: }
81:
82: Output:
83: Creating document with: Test Document
84: Implementing the Read Method for IStorable
85: Implementing Compress
86: Document Status: -1
pustaka: “Learning C# 2005”, Jesse Liberty, Brian MacDonald, O’Reilly 2006