Versioning dengan Override dan New Keywords


Bahasa C # dirancang agar versi antara basis dan class turunan di berbagai libraries dapat berkembang dan menjaga kompatibilitasnya. Ini berarti, misalnya, bahwa pengenalan new member di base class dengan nama yang sama dengan member class turunan benar-benar didukung oleh C # dan tidak menimbulkan perilaku yang tidak terduga.

Ini juga berarti bahwa sebuah class harus secara eksplisit menyatakan apakah sebuah metod d imaksudkan untuk menggantikan metod yang inherited, atau apakah metod tersebut adalah metod baru yang menyembunyikan metode inheritance bernama yang serupa.

Dalam C #, class turunan dapat berisi metod dengan nama yang sama dengan metod base class.
1. Metod base class harus didefinisikan virtual.
2. Jika metod di class turunan tidak didahului oleh keyword new atau keyword pengganti, compiler akan mengeluarkan peringatan dan metod akan berperilaku seolah keyword new ada.
3. Jika metod di class turunan didahului dengan keyword new, metod didefinisikan sebagai metod independen di base class.
4. Jika metod di class turunan didahului dengan keyword yang override, objek class turunan akan memanggil metod itu alih-alih metod base class.
5. Metode base class dapat dipanggil dari dalam class turunan menggunakan keyword base.
6. Keyword Override, virtual, dan keyword new juga dapat diterapkan pada properti, indexers, dan events.
Secara default, metode C # tidak virtual. Jika sebuah metod dinyatakan sebagai virtual, setiap class yang inheritance metod tersebut dapat menerapkan versinya sendiri.

Untuk membuat metod virtual, pengubah virtual digunakan dalam deklarasi metod base class. Class turunan kemudian dapat mengesampingkan metod virtual base dengan menggunakan keyword override atau menyembunyikan metod virtual di base class dengan menggunakan keyword new.

Jika tidak ada keyword override atau keyword new ditentukan, compiler akan mengeluarkan peringatan dan metod di class turunan akan menyembunyikan metod di base class. Untuk menunjukkan hal ini dalam praktiknya, anggap bahwa Company A telah menciptakan sebuah class bernama GraphicsClass, yang digunakan program kita. Berikut ini adalah GraphicsClass:

class GraphicsClass
{
    public virtual void DrawLine() { }
    public virtual void DrawPoint() { }
}
Company kita menggunakan class ini, dan kita menggunakannya untuk mendapatkan class kita sendiri, menambahkan metod baru:
class YourDerivedGraphicsClass : GraphicsClass
{
    public void DrawRectangle() { }
}
Aplikasi kita digunakan tanpa masalah, sampai Company A merilis versi baru GraphicsClass, yang menyerupai code berikut:
class GraphicsClass
{
    public virtual void DrawLine() { }
    public virtual void DrawPoint() { }
    public virtual void DrawRectangle() { }
}
Versi baru GraphicsClass sekarang berisi metod bernama DrawRectangle. Awalnya, tidak ada yang terjadi. Versi baru masih kompatibel dengan versi lama. Setiap perangkat lunak yang telah kita gunakan akan terus bekerja, bahkan jika class baru diinstal pada sistem komputer tersebut.

Setiap panggilan yang ada ke metod DrawRectangle akan terus merujuk versi Anda, di class turunan kita. Namun, segera setelah kita mengkompilasi ulang aplikasi kita dengan menggunakan versi GraphicsClass yang baru, kita akan menerima peringatan dari compiler, CS0108.

Peringatan ini memberi tahu kita bahwa Anda harus mempertimbangkan bagaimana kita ingin metode DrawRectangle kita berperilaku dalam aplikasi kita. Jika kita ingin metod kita mengganti metod base class yang baru, gunakan keyword override:

class YourDerivedGraphicsClass : GraphicsClass
{
    public override void DrawRectangle() { }
}
Keyword yang override memastikan bahwa objek yang berasal dari YourDerivedGraphicsClass akan menggunakan versi base class dari DrawRectangle.

Objek yang berasal dari YourDerivedGraphicsClass masih dapat mengakses versi base class DrawRectangle dengan menggunakan base keyword:
base.DrawRectangle();
Jika kita tidak ingin metod kita mengganti metod base class yang baru, pertimbangan berikut berlaku. Untuk menghindari kebingungan antara kedua metod tersebut, kita bisa mengganti nama metod kita. Ini bisa memakan waktu dan rawan kesalahan, dan tidak praktis dalam beberapa kasus.

 Namun, jika proyek kita relatif kecil, kita dapat menggunakan opsi Refactoring Visual Studio untuk mengganti nama metod. Sebagai alternatif, Anda dapat mencegah peringatan tersebut dengan menggunakan keyword new dalam definisi class turunan kita:
class YourDerivedGraphicsClass : GraphicsClass
{
    public new void DrawRectangle() { }
}
Menggunakan keyword new memberitahu compiler bahwa definisi kita menyembunyikan definisi yang terkandung di base class. Ini adalah default behavior.

  • Override dan Method Selection


Ketika sebuah metod diberi nama di class, kompiler C # memilih metod terbaik untuk dipanggil jika lebih dari satu metod kompatibel dengan panggilan, seperti bila ada dua metod dengan nama yang sama, dan parameter yang sesuai dengan parameter yang di pass .

Metode berikut akan kompatibel:
public class Derived : Base
{
    public override void DoWork(int param) { }
    public void DoWork(double param) { }
}
Ketika DoWork dipanggil pada instance dari Derived, compiler C # pertama-tama akan mencoba membuat panggilan yang kompatibel dengan versi DoWork yang dideklarasikan semula pada Derived.

Metod override tidak dianggap dideklarasikan di class, ini merupakan implementasi baru dari metod yang dideklarasikan di base class. Hanya jika kompiler C # tidak dapat mencocokkan pemanggilan metod dengan metod asli pada Derived akan mencoba mencocokkan panggilan dengan metod yang diganti dengan nama dan parameter yang kompatibel. Sebagai contoh:
int val = 5;
Derived d = new Derived();
d.DoWork(val);  // Calls DoWork(double).
Karena variabel val dapat dikonversi menjadi doubel secara implisit, compiler C # memanggil DoWork (double) instead DoWork (int). Ada dua cara untuk menghindarinya.

Pertama, hindari menyatakan metod new dengan nama yang sama dengan metod virtual.

Kedua, kita dapat menginstruksikan compiler C # untuk memanggil metod virtual dengan membuatnya mencari daftar metod base class dengan memasukkan instance dari Derived to Base. Karena metodenya bersifat virtual, maka implementasi DoWork (int) pada Derived akan dipanggil. Sebagai contoh:
((Base)d).DoWork(val);  // Calls DoWork(int) on Derived.
Previous
Next Post »