Knowing When to Use Override and New Keywords


Dalam C #, sebuah metode di class turunan dapat memiliki nama yang sama dengan metode di base class. Kita dapat menentukan bagaimana metode berinteraksi dengan menggunakan keyword new dan mengesampingkan keyword.

Override modifier memperpanjang metod base class, dan new modifier menyembunyikannya. Perbedaannya diilustrasikan dalam contoh dalam topik ini.

Dalam aplikasi konsol, nyatakan dua class berikut, BaseClass dan DerivedClass. DerivedClass inherits dari BaseClass.
class BaseClass  
{  
    public void Method1()  
    {  
        Console.WriteLine("Base - Method1");  
    }  
}  

class DerivedClass : BaseClass  
{  
    public void Method2()  
    {  
        Console.WriteLine("Derived - Method2");  
    }  
}
Pada Main metod, deklarasikan variabel bc, dc, dan bcdc.
1. bc adalah tipe data BaseClass, dan nilainya adalah tipe data BaseClass.
2. dc adalah tipe data DerivedClass, dan nilainya adalah tipe data DerivedClass.
3. bcdc adalah tipe data BaseClass, dan nilainya adalah tipe data DerivedClass.

Inilah variabel yang perlu diperhatikan. Karena bc dan bcdc memiliki tipe data BaseClass, mereka hanya bisa mengakses Method1, kecuali jika kita menggunakan casting.

Variabel dc dapat mengakses kedua metode1 dan metode2. Hubungan ini ditunjukkan dalam kode berikut.
class Program  
{  
    static void Main(string[] args)  
    {  
        BaseClass bc = new BaseClass();  
        DerivedClass dc = new DerivedClass();  
        BaseClass bcdc = new DerivedClass();  

        bc.Method1();  
        dc.Method1();  
        dc.Method2();  
        bcdc.Method1();  
    }  
    // Output:  
    // Base - Method1  
    // Base - Method1  
    // Derived - Method2  
    // Base - Method1  
}  
Selanjutnya, tambahkan metode Method2 berikut ke BaseClass. Sign metod ini sesuai dengan sign metod Method2 di DerivedClass.
public void Method2()  
{  
    Console.WriteLine("Base - Method2");  
}  
Karena BaseClass sekarang memiliki metod Method2, pernyataan panggilan kedua dapat ditambahkan untuk variabel BaseClass bc dan bcdc, seperti yang ditunjukkan pada code berikut.
bc.Method1();  
bc.Method2();  
dc.Method1();  
dc.Method2();  
bcdc.Method1();  
bcdc.Method2();  
Ketika kita membangun sebuah proyek, Kita melihat bahwa penambahan metod Method2 di BaseClass menyebabkan peringatan. Peringatan tersebut mengatakan bahwa metod Method2 di DerivedClass menyembunyikan metod Method2 di BaseClass.

Kita disarankan untuk menggunakan keyword new dalam definisi Method2 jika Kita bermaksud membuat hasilnya. Sebagai alternatif, kita bisa mengganti nama salah satu metod Method2 untuk menyelesaikan peringatan, tapi itu tidak selalu praktis.

Sebelum menambahkan yang baru, jalankan program untuk melihat output yang dihasilkan oleh pernyataan panggilan tambahan. Hasil berikut akan ditampilkan.
// Output:  
// Base - Method1  
// Base - Method2  
// Base - Method1  
// Derived - Method2  
// Base - Method1  
// Base - Method2 
Keyword new mempertahankan hubungan yang menghasilkan output itu, namun menekan peringatan tersebut.

Variabel yang memiliki tipe data BaseClass terus mengakses member BaseClass, dan variabel yang memiliki tipe data DerivedClass terus mengakses member di DerivedClass terlebih dahulu, dan kemudian mempertimbangkan membernya yang berasal dari BaseClass.

Untuk menekan peringatan tersebut, tambahkan modifier baru ke definisi Method2 di DerivedClass, seperti yang ditunjukkan pada code berikut. Modifier dapat ditambahkan sebelum atau sesudah public.
public new void Method2()  
{  
    Console.WriteLine("Derived - Method2");  
}  
Jalankan program lagi untuk memverifikasi bahwa output tidak berubah. Juga verifikasi bahwa peringatan tersebut tidak lagi muncul. Dengan menggunakan yang baru, kita menyatakan bahwa kita sadar bahwa member yang mengubahnya menyembunyikan member yang inherit dari base class. 

Untuk membedakan behavior ini dengan efek menggunakan override, tambahkan metod berikut ke DerivedClass. Override modifier dapat ditambahkan sebelum atau sesudah public.
public override void Method1()  
{  
    Console.WriteLine("Derived - Method1");  
}  
Tambahkan modifier virtual ke definisi Method1 di BaseClass. Modifier virtual dapat ditambahkan sebelum atau sesudah public.
public virtual void Method1()  
{  
    Console.WriteLine("Base - Method1");  
}  
Jalankan proyek lagi. Perhatikan terutama dua baris terakhir dari output berikut.
// Output:  
// Base - Method1  
// Base - Method2  
// Derived - Method1  
// Derived - Method2  
// Derived - Method1  
// Base - Method2  
Penggunaan modifier override memungkinkan bcdc untuk mengakses metod Method1 yang didefinisikan dalam DerivedClass.

Biasanya, ini adalah perilaku yang diinginkan dalam hirarki inheritance. Kita ingin objek yang memiliki nilai yang dibuat dari class derived menggunakan metod yang didefinisikan di class derived.

kita mencapai perilaku ini dengan menggunakan metod override untuk memperpanjang metod base class. 1 Code berikut berisi contoh lengkap.
using System;  
using System.Text;  

namespace OverrideAndNew  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            BaseClass bc = new BaseClass();  
            DerivedClass dc = new DerivedClass();  
            BaseClass bcdc = new DerivedClass();  

            // The following two calls do what you would expect. They call  
            // the methods that are defined in BaseClass.  
            bc.Method1();  
            bc.Method2();  
            // Output:  
            // Base - Method1  
            // Base - Method2  

            // The following two calls do what you would expect. They call  
            // the methods that are defined in DerivedClass.  
            dc.Method1();  
            dc.Method2();  
            // Output:  
            // Derived - Method1  
            // Derived - Method2  

            // The following two calls produce different results, depending   
            // on whether override (Method1) or new (Method2) is used.  
            bcdc.Method1();  
            bcdc.Method2();  
            // Output:  
            // Derived - Method1  
            // Base - Method2  
        }  
    }  

    class BaseClass  
    {  
        public virtual void Method1()  
        {  
            Console.WriteLine("Base - Method1");  
        }  

        public virtual void Method2()  
        {  
            Console.WriteLine("Base - Method2");  
        }  
    }  

    class DerivedClass : BaseClass  
    {  
        public override void Method1()  
        {  
            Console.WriteLine("Derived - Method1");  
        }  

        public new void Method2()  
        {  
            Console.WriteLine("Derived - Method2");  
        }  
    }  
}  
Contoh berikut menggambarkan perilaku serupa dalam konteks yang berbeda. Contohnya mendefinisikan tiga class: base class bernama Car dan dua class yang berasal darinya, ConvertibleCar and Minivan.

Base class berisi metod DescribeCar. Metod ini menampilkan deskripsi base car, dan kemudian memanggil ShowDetails untuk memberikan informasi tambahan. Masing-masing dari tiga class mendefinisikan metode ShowDetails.

Modifier baru digunakan untuk mendefinisikan ShowDetails di class ConvertibleCar. Override Modifier digunakan untuk mendefinisikan ShowDetails di class Minivan.
// Define the base class, Car. The class defines two methods,  
// DescribeCar and ShowDetails. DescribeCar calls ShowDetails, and each derived  
// class also defines a ShowDetails method. The example tests which version of  
// ShowDetails is selected, the base class method or the derived class method.  
class Car  
{  
    public void DescribeCar()  
    {  
        System.Console.WriteLine("Four wheels and an engine.");  
        ShowDetails();  
    }  

    public virtual void ShowDetails()  
    {  
        System.Console.WriteLine("Standard transportation.");  
    }  
}  

// Define the derived classes.  

// Class ConvertibleCar uses the new modifier to acknowledge that ShowDetails  
// hides the base class method.  
class ConvertibleCar : Car  
{  
    public new void ShowDetails()  
    {  
        System.Console.WriteLine("A roof that opens up.");  
    }  
}  

// Class Minivan uses the override modifier to specify that ShowDetails  
// extends the base class method.  
class Minivan : Car  
{  
    public override void ShowDetails()  
    {  
        System.Console.WriteLine("Carries seven people.");  
    }  
}  
Tes contoh disebut versi ShowDetails. Metod berikut, TestCars1, menyatakan sebuah instance dari setiap class, dan kemudian memanggil DeskcribeCar pada setiap contohnya.
public static void TestCars1()  
{  
    System.Console.WriteLine("\nTestCars1");  
    System.Console.WriteLine("----------");  

    Car car1 = new Car();  
    car1.DescribeCar();  
    System.Console.WriteLine("----------");  

    // Notice the output from this test case. The new modifier is  
    // used in the definition of ShowDetails in the ConvertibleCar  
    // class.    

    ConvertibleCar car2 = new ConvertibleCar();  
    car2.DescribeCar();  
    System.Console.WriteLine("----------");  

    Minivan car3 = new Minivan();  
    car3.DescribeCar();  
    System.Console.WriteLine("----------");  
}  
TestCars1 menghasilkan output berikut. Perhatikan terutama hasil untuk car2, yang mungkin bukan yang kita harapkan. Type objeknya adalah ConvertibleCar, tapi DeskcribeCar tidak mengakses versi ShowDetails yang didefinisikan di class ConvertibleCar karena metod tersebut dideklarasikan dengan modifier baru, bukan override modifier.

Akibatnya, objek ConvertibleCar menampilkan deskripsi yang sama dengan objek Car. Bandingkan hasilnya untuk car3, yang merupakan objek Minivan. Dalam kasus ini, metode ShowDetails yang dideklarasikan di class Minivan mengesampingkan metod ShowDetails yang dideklarasikan di class Car, dan deskripsi yang ditampilkan menggambarkan minivan.
// TestCars1  
// ----------  
// Four wheels and an engine.  
// Standard transportation.  
// ----------  
// Four wheels and an engine.  
// Standard transportation.  
// ----------  
// Four wheels and an engine.  
// Carries seven people.  
// ----------  
TestCars2 create list objek yang memiliki tipe data Car. Values objek di instantiasikan dari class Car, ConvertibleCar, dan Minivan. Deskripsikan Car dipanggil pada setiap elemen dalam daftar. Code berikut menunjukkan definisi TestCars2.
public static void TestCars2()  
{  
    System.Console.WriteLine("\nTestCars2");  
    System.Console.WriteLine("----------");  

    var cars = new List { new Car(), new ConvertibleCar(),   
        new Minivan() };  

    foreach (var car in cars)  
    {  
        car.DescribeCar();  
        System.Console.WriteLine("----------");  
    }  
}  
Output berikut ditampilkan. Perhatikan bahwa itu sama dengan output yang ditampilkan oleh TestCars1. Metod ShowDetails dari class ConvertibleCar tidak disebut, terlepas dari apakah tipe data objeknya adalah ConvertibleCar, seperti pada TestCars1, atau Car, seperti pada TestCars2.

Sebaliknya, car3 memanggil metod ShowDetails dari class Minivan dalam kedua kasus tersebut, apakah itu memiliki tipe data Minivan atau Type Car.
// TestCars2  
// ----------  
// Four wheels and an engine.  
// Standard transportation.  
// ----------  
// Four wheels and an engine.  
// Standard transportation.  
// ----------  
// Four wheels and an engine.  
// Carries seven people.  
// ----------  
Metod TestCars3 dan TestCars4 selesaikan contohnya. Metode ini memanggil ShowDetails secara langsung, pertama dari objek yang dideklarasikan untuk memiliki tipe data ConvertibleCar dan Minivan (TestCars3), kemudian dari objek yang dinyatakan memiliki tipe Car (TestCars4). Kode berikut mendefinisikan kedua metod ini.
public static void TestCars3()  
{  
    System.Console.WriteLine("\nTestCars3");  
    System.Console.WriteLine("----------");  
    ConvertibleCar car2 = new ConvertibleCar();  
    Minivan car3 = new Minivan();  
    car2.ShowDetails();  
    car3.ShowDetails();  
}  

public static void TestCars4()  
{  
    System.Console.WriteLine("\nTestCars4");  
    System.Console.WriteLine("----------");  
    Car car2 = new ConvertibleCar();  
    Car car3 = new Minivan();  
    car2.ShowDetails();  
    car3.ShowDetails();  
}  
Metod menghasilkan output berikut, yang sesuai dengan hasil dari contoh pertama dalam topik ini.
// TestCars3  
// ----------  
// A roof that opens up.  
// Carries seven people.  

// TestCars4  
// ----------  
// Standard transportation.  
// Carries seven people. 
Code berikut menunjukkan proyek yang lengkap dan hasilnya.
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  

namespace OverrideAndNew2  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            // Declare objects of the derived classes and test which version  
            // of ShowDetails is run, base or derived.  
            TestCars1();  

            // Declare objects of the base class, instantiated with the  
            // derived classes, and repeat the tests.  
            TestCars2();  

            // Declare objects of the derived classes and call ShowDetails  
            // directly.  
            TestCars3();  

            // Declare objects of the base class, instantiated with the  
            // derived classes, and repeat the tests.  
            TestCars4();  
        }  

        public static void TestCars1()  
        {  
            System.Console.WriteLine("\nTestCars1");  
            System.Console.WriteLine("----------");  

            Car car1 = new Car();  
            car1.DescribeCar();  
            System.Console.WriteLine("----------");  

            // Notice the output from this test case. The new modifier is  
            // used in the definition of ShowDetails in the ConvertibleCar  
            // class.    
            ConvertibleCar car2 = new ConvertibleCar();  
            car2.DescribeCar();  
            System.Console.WriteLine("----------");  

            Minivan car3 = new Minivan();  
            car3.DescribeCar();  
            System.Console.WriteLine("----------");  
        }  
        // Output:  
        // TestCars1  
        // ----------  
        // Four wheels and an engine.  
        // Standard transportation.  
        // ----------  
        // Four wheels and an engine.  
        // Standard transportation.  
        // ----------  
        // Four wheels and an engine.  
        // Carries seven people.  
        // ----------  

        public static void TestCars2()  
        {  
            System.Console.WriteLine("\nTestCars2");  
            System.Console.WriteLine("----------");  

            var cars = new List { new Car(), new ConvertibleCar(),   
                new Minivan() };  

            foreach (var car in cars)  
            {  
                car.DescribeCar();  
                System.Console.WriteLine("----------");  
            }  
        }  
        // Output:  
        // TestCars2  
        // ----------  
        // Four wheels and an engine.  
        // Standard transportation.  
        // ----------  
        // Four wheels and an engine.  
        // Standard transportation.  
        // ----------  
        // Four wheels and an engine.  
        // Carries seven people.  
        // ----------  

        public static void TestCars3()  
        {  
            System.Console.WriteLine("\nTestCars3");  
            System.Console.WriteLine("----------");  
            ConvertibleCar car2 = new ConvertibleCar();  
            Minivan car3 = new Minivan();  
            car2.ShowDetails();  
            car3.ShowDetails();  
        }  
        // Output:  
        // TestCars3  
        // ----------  
        // A roof that opens up.  
        // Carries seven people.  

        public static void TestCars4()  
        {  
            System.Console.WriteLine("\nTestCars4");  
            System.Console.WriteLine("----------");  
            Car car2 = new ConvertibleCar();  
            Car car3 = new Minivan();  
            car2.ShowDetails();  
            car3.ShowDetails();  
        }  
        // Output:  
        // TestCars4  
        // ----------  
        // Standard transportation.  
        // Carries seven people.  
    }  

    // Define the base class, Car. The class defines two virtual methods,  
    // DescribeCar and ShowDetails. DescribeCar calls ShowDetails, and each derived  
    // class also defines a ShowDetails method. The example tests which version of  
    // ShowDetails is used, the base class method or the derived class method.  
    class Car  
    {  
        public virtual void DescribeCar()  
        {  
            System.Console.WriteLine("Four wheels and an engine.");  
            ShowDetails();  
        }  

        public virtual void ShowDetails()  
        {  
            System.Console.WriteLine("Standard transportation.");  
        }  
    }  

    // Define the derived classes.  

    // Class ConvertibleCar uses the new modifier to acknowledge that ShowDetails  
    // hides the base class method.  
    class ConvertibleCar : Car  
    {  
        public new void ShowDetails()  
        {  
            System.Console.WriteLine("A roof that opens up.");  
        }  
    }  

    // Class Minivan uses the override modifier to specify that ShowDetails  
    // extends the base class method.  
    class Minivan : Car  
    {  
        public override void ShowDetails()  
        {  
            System.Console.WriteLine("Carries seven people.");  
        }  
    }  

}  
Previous
Next Post »