Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Dalam C#, metode dalam kelas turunan dapat memiliki nama yang sama dengan metode di kelas dasar. Anda dapat menentukan bagaimana metode berinteraksi dengan menggunakan kata kunci new dan override. Pengubah override
memperluas metode kelas virtual
dasar, dan pengubah new
menyembunyikan metode kelas dasar yang dapat diakses. Perbedaannya diilustrasikan dalam contoh dalam topik ini.
Dalam aplikasi konsol, deklarasikan dua kelas berikut, BaseClass
dan DerivedClass
.
DerivedClass
mewarisi dari BaseClass
.
class BaseClass
{
public void Method1()
{
Console.WriteLine("Base - Method1");
}
}
class DerivedClass : BaseClass
{
public void Method2()
{
Console.WriteLine("Derived - Method2");
}
}
Dalam metode , Main
deklarasikan variabel bc
, , dc
dan bcdc
.
bc
berjenisBaseClass
, dan nilainya berjenisBaseClass
.dc
berjenisDerivedClass
, dan nilainya berjenisDerivedClass
.bcdc
berjenisBaseClass
, dan nilainya berjenisDerivedClass
. Ini adalah variabel yang perlu diperhatikan.
Karena bc
dan bcdc
memiliki jenis BaseClass
, mereka hanya dapat langsung mengakses Method1
, kecuali Anda menggunakan casting. Variabel dc
dapat mengakses baik Method1
maupun Method2
. Hubungan ini ditampilkan 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 berikut Method2
ke BaseClass
. Tanda tangan metode ini sesuai dengan tanda tangan metode Method2
di DerivedClass
.
public void Method2()
{
Console.WriteLine("Base - Method2");
}
Karena BaseClass
sekarang memiliki Method2
metode, pernyataan panggilan kedua dapat ditambahkan untuk BaseClass
variabel bc
dan bcdc
, seperti yang ditunjukkan dalam kode berikut.
bc.Method1();
bc.Method2();
dc.Method1();
dc.Method2();
bcdc.Method1();
bcdc.Method2();
Saat Anda membangun proyek, Anda melihat bahwa penambahan Method2
metode dalam BaseClass
menyebabkan peringatan. Peringatan mengatakan bahwa metode Method2
yang ada di DerivedClass
menyembunyikan metode Method2
yang ada di BaseClass
. Anda disarankan untuk menggunakan new
kata kunci dalam Method2
definisi jika Anda ingin menyebabkan hasil tersebut. Atau, Anda dapat mengganti nama salah satu metode Method2
untuk menyelesaikan peringatan, tetapi itu tidak selalu praktis.
Sebelum menambahkan new
, jalankan program untuk melihat output yang dihasilkan oleh pernyataan panggilan tambahan. Hasil berikut ditampilkan.
// Output:
// Base - Method1
// Base - Method2
// Base - Method1
// Derived - Method2
// Base - Method1
// Base - Method2
Kata kunci new
menjaga hubungan yang menghasilkan output tersebut, tetapi menghilangkan peringatannya. Variabel dengan tipe BaseClass
terus mengakses anggota dari BaseClass
, dan variabel dengan tipe DerivedClass
terus mengakses anggota di DerivedClass
terlebih dahulu, kemudian mempertimbangkan anggota yang diwarisi dari BaseClass
.
Untuk menekan peringatan, tambahkan pengubah new
ke definisi Method2
dalam DerivedClass
, seperti yang ditunjukkan dalam kode berikut. Pengubah dapat ditambahkan sebelum atau sesudah public
.
public new void Method2()
{
Console.WriteLine("Derived - Method2");
}
Jalankan program lagi untuk memverifikasi bahwa output tidak berubah. Verifikasi juga bahwa peringatan tidak lagi muncul. Dengan menggunakan new
, Anda menegaskan bahwa Anda menyadari bahwa anggota yang dimodifikasi menyembunyikan anggota yang diwarisi dari kelas dasar. Untuk informasi selengkapnya tentang penyembunyian nama melalui pewarisan, lihat Modifier baru.
Untuk membedakan perilaku ini dengan efek penggunaan override
, tambahkan metode berikut ke DerivedClass
. Pengubah override
dapat ditambahkan sebelum atau sesudah public
.
public override void Method1()
{
Console.WriteLine("Derived - Method1");
}
Tambahkan pengubah virtual
ke definisi Method1
dalam BaseClass
. Pengubah 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 pengubah override
memungkinkan bcdc
untuk mengakses Method1
metode yang ditentukan dalam DerivedClass
. Biasanya, itu adalah perilaku yang diinginkan dalam hierarki warisan. Anda ingin objek yang memiliki nilai yang dibuat dari kelas turunan menggunakan metode yang ditentukan dalam kelas turunan. Anda mencapai perilaku tersebut dengan menggunakan override
untuk memperluas metode kelas dasar.
Kode 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 mengilustrasikan perilaku serupa dalam konteks yang berbeda. Contohnya mendefinisikan tiga kelas: kelas dasar bernama Car
dan dua kelas yang berasal dari kelas tersebut, ConvertibleCar
dan Minivan
. Kelas dasar berisi DescribeCar
metode . Metode ini menampilkan deskripsi dasar mobil, lalu memanggil ShowDetails
untuk memberikan informasi tambahan. Masing-masing dari tiga kelas mendefinisikan metode ShowDetails
. Pengubah new
digunakan untuk menentukan ShowDetails
di ConvertibleCar
kelas . Pengubah override
digunakan untuk menentukan ShowDetails
di Minivan
kelas .
// 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.");
}
}
Contoh tersebut menguji versi mana dari ShowDetails
yang dipanggil. Metode berikut, TestCars1
, mendeklarasikan instans dari setiap kelas, lalu memanggil pada setiap instans DescribeCar
.
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 Anda harapkan. Tipe objek adalah ConvertibleCar
, tetapi DescribeCar
tidak mengakses versi ShowDetails
yang ditentukan di kelas ConvertibleCar
karena metode ini dideklarasikan dengan pengubah new
, bukan pengubah override
. Akibatnya, ConvertibleCar
objek menampilkan deskripsi yang sama dengan Car
objek. Bandingkan hasil untuk car3
, yang merupakan objek Minivan
. Dalam hal ini, ShowDetails
metode yang dideklarasikan dalam Minivan
kelas mengambil alih ShowDetails
metode yang dideklarasikan di Car
kelas, 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
membuat daftar objek yang memiliki tipe Car
. Nilai objek diinisialisasi dari kelas Car
, ConvertibleCar
, dan Minivan
.
DescribeCar
dipanggil pada setiap elemen daftar. Kode berikut menunjukkan definisi TestCars2
.
public static void TestCars2()
{
System.Console.WriteLine("\nTestCars2");
System.Console.WriteLine("----------");
var cars = new List<Car> { new Car(), new ConvertibleCar(),
new Minivan() };
foreach (var car in cars)
{
car.DescribeCar();
System.Console.WriteLine("----------");
}
}
Berikut adalah output yang ditampilkan. Perhatikan bahwa itu sama dengan output yang ditampilkan oleh TestCars1
. Metode ShowDetails
dari kelas ConvertibleCar
tidak dipanggil, terlepas dari apakah tipe objek adalah ConvertibleCar
, seperti dalam TestCars1
, atau Car
, seperti dalam TestCars2
. Sebaliknya, car3
memanggil metode ShowDetails
dari kelas Minivan
dalam kedua kasus, apakah memiliki jenis Minivan
atau jenis Car
.
// TestCars2
// ----------
// Four wheels and an engine.
// Standard transportation.
// ----------
// Four wheels and an engine.
// Standard transportation.
// ----------
// Four wheels and an engine.
// Carries seven people.
// ----------
Metode TestCars3
dan TestCars4
melengkapi contoh. Metode ini memanggil ShowDetails
secara langsung, pertama dari objek yang dinyatakan memiliki jenis ConvertibleCar
dan Minivan
(TestCars3
), kemudian dari objek yang dinyatakan memiliki jenis Car
(TestCars4
). Kode berikut mendefinisikan dua metode 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();
}
Metode 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.
Kode berikut menunjukkan proyek lengkap dan outputnya.
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<Car> { 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.");
}
}
}