Geçersiz Kılmanın ve Yeni Anahtar Sözcüklerin Ne Zaman Kullanılacağını Bilme (C# Programlama Kılavuzu)
C# dilinde, türetilmiş bir sınıftaki bir yöntem, temel sınıftaki bir yöntemle aynı ada sahip olabilir. Yöntemlerin yeni ve geçersiz kılma anahtar sözcüklerini kullanarak nasıl etkileşim kuracağını belirtebilirsiniz. Değiştirici, temel sınıf virtual
yöntemini genişletir ve new
değiştirici erişilebilir bir temel sınıf yöntemini gizler.override
Fark, bu konudaki örneklerde gösterilmiştir.
Konsol uygulamasında aşağıdaki iki sınıfı BaseClass
ve DerivedClass
bildirin. DerivedClass
öğesinden BaseClass
devralır.
class BaseClass
{
public void Method1()
{
Console.WriteLine("Base - Method1");
}
}
class DerivedClass : BaseClass
{
public void Method2()
{
Console.WriteLine("Derived - Method2");
}
}
yönteminde Main
, dc
ve bcdc
değişkenlerini bc
bildirin.
bc
türündedirBaseClass
ve değeri türündedirBaseClass
.dc
türündedirDerivedClass
ve değeri türündedirDerivedClass
.bcdc
türündedirBaseClass
ve değeri türündedirDerivedClass
. Bu, dikkate alınacak değişkendir.
ve bc
bcdc
türüne BaseClass
sahip olduğundan, atama kullanmadığınız sürece yalnızca doğrudan erişebilirler Method1
. Değişken dc
hem hem de Method1
Method2
öğesine erişebilir. Bu ilişkiler aşağıdaki kodda gösterilmiştir.
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
}
Ardından, aşağıdaki Method2
yöntemi öğesine BaseClass
ekleyin. Bu yöntemin imzası içindeki DerivedClass
yöntemin imzası ile Method2
eşleşir.
public void Method2()
{
Console.WriteLine("Base - Method2");
}
Artık bir yöntemi olduğundanBaseClass
, aşağıdaki kodda gösterildiği gibi ve bcdc
değişkenleri bc
için BaseClass
ikinci bir çağırma deyimi Method2
eklenebilir.
bc.Method1();
bc.Method2();
dc.Method1();
dc.Method2();
bcdc.Method1();
bcdc.Method2();
Projeyi oluştururken yönteminin eklenmesinin bir uyarıya Method2
BaseClass
neden olduğunu görürsünüz. Uyarı, içindeki yönteminin Method2
içindeki BaseClass
yöntemini gizlediğini Method2
söyler.DerivedClass
Bu sonuda neden olmak istiyorsanız tanımda Method2
anahtar sözcüğünü kullanmanız new
tavsiye edilir. Alternatif olarak, uyarıyı Method2
çözümlemek için yöntemlerden birini yeniden adlandırabilirsiniz, ancak bu her zaman pratik değildir.
eklemeden new
önce, ek çağrı deyimleri tarafından üretilen çıkışı görmek için programı çalıştırın. Aşağıdaki sonuçlar görüntülenir.
// Output:
// Base - Method1
// Base - Method2
// Base - Method1
// Derived - Method2
// Base - Method1
// Base - Method2
new
anahtar sözcüğü, bu çıkışı oluşturan ilişkileri korur, ancak uyarıyı gizler. Türü BaseClass
olan değişkenler, üyelerine BaseClass
erişmeye devam eder ve türü DerivedClass
olan değişken ilk olarak üyelere DerivedClass
erişmeye ve ardından öğesinden BaseClass
devralınan üyeleri dikkate almaya devam eder.
Uyarıyı engellemek için, değiştiriciyi new
aşağıdaki kodda DerivedClass
gösterildiği gibi içindeki tanımına Method2
ekleyin. Değiştirici, öncesinde veya sonrasında public
eklenebilir.
public new void Method2()
{
Console.WriteLine("Derived - Method2");
}
Çıkışın değişmediğini doğrulamak için programı yeniden çalıştırın. Ayrıca uyarının artık görünmediğini doğrulayın. kullanarak new
, değiştirdiği üyenin temel sınıftan devralınan bir üyeyi gizlediğinin farkında olduğunuzu onaylarsınız. Devralma yoluyla ad gizleme hakkında daha fazla bilgi için bkz . yeni Değiştirici.
Bu davranışı kullanmanın override
etkilerine karşıtlık sağlamak için, öğesine aşağıdaki yöntemi DerivedClass
ekleyin. Değiştirici, override
öncesinde veya sonrasında public
eklenebilir.
public override void Method1()
{
Console.WriteLine("Derived - Method1");
}
değiştiricisini virtual
içindeki tanımına Method1
BaseClass
ekleyin. Değiştirici, virtual
öncesinde veya sonrasında public
eklenebilir.
public virtual void Method1()
{
Console.WriteLine("Base - Method1");
}
Projeyi tekrar çalıştırın. Özellikle aşağıdaki çıkışın son iki satırına dikkat edin.
// Output:
// Base - Method1
// Base - Method2
// Derived - Method1
// Derived - Method2
// Derived - Method1
// Base - Method2
Değiştiricinin override
kullanılması, içinde DerivedClass
tanımlanan yönteme Method1
erişmenizi sağlarbcdc
. Genellikle, devralma hiyerarşilerinde istenen davranış budur. Türetilmiş sınıftan oluşturulan değerlere sahip nesnelerin türetilmiş sınıfta tanımlanan yöntemleri kullanmasını istiyorsunuz. Temel sınıf yöntemini genişletmek için kullanarak override
bu davranışı elde edebilirsiniz.
Aşağıdaki kod, tam örneği içerir.
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");
}
}
}
Aşağıdaki örnekte farklı bir bağlamda benzer davranışlar gösterilmektedir. Örnek üç sınıf tanımlar: adlı Car
bir temel sınıf ve ondan ConvertibleCar
türetilen iki sınıf ve Minivan
. Temel sınıf bir DescribeCar
yöntem içerir. yöntemi, bir arabanın temel açıklamasını görüntüler ve daha sonra ek bilgi sağlamak için arar ShowDetails
. Üç sınıfın her biri bir ShowDetails
yöntem tanımlar. new
değiştirici, sınıfında ConvertibleCar
tanımlamak ShowDetails
için kullanılır. override
değiştirici, sınıfında Minivan
tanımlamak ShowDetails
için kullanılır.
// 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.");
}
}
Örnek, hangi sürümünün ShowDetails
çağrıldığını test ediyor. Aşağıdaki yöntemi, TestCars1
her sınıfın bir örneğini bildirir ve ardından her örneği çağırır 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
aşağıdaki çıkışı üretir. Özellikle beklediğiniz gibi olmayan sonuçlarına car2
dikkat edin. nesnesinin türü şeklindedirConvertibleCar
, ancak DescribeCar
bu yöntem değiştiriciyle değil değiştiriciyle bildirildiğinden new
sınıfında tanımlanan ConvertibleCar
sürümüne ShowDetails
override
erişmez. Sonuç olarak, bir ConvertibleCar
nesne nesneyle aynı açıklamayı Car
görüntüler. Bir nesne olan için car3
sonuçların karşıtlığını Minivan
belirleyin. Bu durumda, ShowDetails
sınıfında bildirilen Minivan
yöntemi sınıfında bildirilen Car
yöntemini geçersiz kılar ShowDetails
ve görüntülenen açıklama bir minivan açıklar.
// TestCars1
// ----------
// Four wheels and an engine.
// Standard transportation.
// ----------
// Four wheels and an engine.
// Standard transportation.
// ----------
// Four wheels and an engine.
// Carries seven people.
// ----------
TestCars2
türüne Car
sahip nesnelerin listesini oluşturur. Nesnelerin değerleri , ConvertibleCar
ve Minivan
sınıflarından Car
örneği oluşturulur. DescribeCar
, listenin her öğesinde çağrılır. Aşağıdaki kod, tanımını TestCars2
gösterir.
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("----------");
}
}
Aşağıdaki çıkış görüntülenir. tarafından görüntülenen TestCars1
çıkışla aynı olduğuna dikkat edin. nesnesinin ConvertibleCar
ConvertibleCar
türü , veya Car
içinde olduğu gibi TestCars1
olmasına bakılmaksızın sınıfının yöntemi çağrılmazTestCars2
ShowDetails
. Buna karşılık, car3
türü veya türü Minivan
Car
olsun, her iki durumda da sınıfından Minivan
yöntemini çağırırShowDetails
.
// TestCars2
// ----------
// Four wheels and an engine.
// Standard transportation.
// ----------
// Four wheels and an engine.
// Standard transportation.
// ----------
// Four wheels and an engine.
// Carries seven people.
// ----------
Yöntemler TestCars3
ve TestCars4
örneği tamamlayın. Bu yöntemler, önce türü ConvertibleCar
ve () olduğu bildirilen nesnelerden, sonra türü (TestCars3
TestCars4
) olarak bildirilen Car
nesnelerden doğrudan çağrır ShowDetails
Minivan
. Aşağıdaki kod bu iki yöntemi tanımlar.
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();
}
Yöntemler, bu konudaki ilk örnekteki sonuçlara karşılık gelen aşağıdaki çıkışı oluşturur.
// TestCars3
// ----------
// A roof that opens up.
// Carries seven people.
// TestCars4
// ----------
// Standard transportation.
// Carries seven people.
Aşağıdaki kod, projenin tamamını ve çıkışını gösterir.
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.");
}
}
}