Aracılığıyla paylaş


Geçersiz Kılmanın ve Yeni Anahtar Sözcüklerin Ne Zaman Kullanılacağını Bilme (C# Programlama Kılavuzu)

C# [NULL]'ta türetilmiş bir sınıf içinde bir yöntem bir taban sınıfta aynı adı taşıyan bir yöntem olabilir.Yöntemleri kullanarak nasıl etkileşimde bulunduğunu belirtmek Yeni ve geçersiz kılma anahtar sözcükler.override Değiştirici genişleten temel sınıf yöntemi ve new değiştirici gizler onu.Fark, bu konudaki örneklerde gösterilmiştir.

Bir konsol uygulamasında aşağıdaki iki sınıf bildirmek BaseClass ve DerivedClass.DerivedClass, BaseClass'den devralınır.

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

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

In the Main method, declare variables bc, dc, and bcdc.

  • bctür BaseClass, ve değer türü BaseClass.

  • dctür DerivedClass, ve değer türü DerivedClass.

  • bcdctür BaseClass, ve değer türü DerivedClass.Bu dikkat değişkendir.

Çünkü bc ve bcdc türü BaseClass, yalnızca doğrudan erişebilir Method1, çevrim kullanmadığınız sürece.Değişken dc hem erişim Method1 ve Method2.Bu ilişkiler, aşağıdaki kodu gösterilir.

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
}

Sonra aşağıdaki ekleyin Method2 yöntemine BaseClass.Bu yöntem imzası imzası ile eşleşen Method2 yöntemi DerivedClass.

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

Çünkü BaseClass şimdi sahip bir Method2 yöntemi, ikinci bir arama ifade eklenebilir için BaseClass değişkenleri bc ve bcdc, aşağıdaki kodda gösterildiği gibi.

bc.Method1();
bc.Method2();
dc.Method1();
dc.Method2();
bcdc.Method1();
bcdc.Method2();

Proje oluştururken, görmek ve buna ek olarak Method2 yönteminde BaseClass bir uyarı neden olur.Uyarı bildiren Method2 yöntemi DerivedClass gizler Method2 yöntemi BaseClass.Kullanmanız önerilir new bir anahtar sözcük Method2 sonucunda neden düşünüyorsanız tanımı.Alternatif olarak, biri adlandırabilir Method2 uyarı ancak giderme yöntemleri değil her zaman pratik.

Eklemeden önce new, ek arama ifadeler tarafından üretilen çıktı 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üğünü o çıktı üreten ilişkileri korur, ancak uyarıyı bastırır.Türündeki değişkenler BaseClass üyeleri erişmeye devam BaseClass, türünde değişken DerivedClass üyeleri erişmeye devam DerivedClass ilk ve devralınan üyeleri göz önünde BaseClass.

Uyarıyı bastırmak için ekleme new tanımı için değiştirici Method2 , DerivedClass, aşağıdaki kodda gösterildiği gibi.Değiştirici eklenebilir, önce veya sonra public.

public new void Method2()
{
    Console.WriteLine("Derived - Method2");
}

Çıkış değiştirilmediği yeniden doğrulamak için programı çalıştırın.Uyarı artık göründüğünden emin olun.Kullanarak new, onu değiştirir üye temel sınıfından devralınan üyesi gizler farkında çiftidir.Devralma yoluyla adı gizleme hakkında daha fazla bilgi için bkz: new Değiştiricisi (C# Başvurusu).

Bu davranışı kullanarak etkilerini kıyaslamak override, aşağıdaki yönteme ekleyin DerivedClass.override Önce veya sonra değiştirici eklenebilir public.

public override void Method1()
{
    Console.WriteLine("Derived - Method1");
}

Ekleme virtual tanımı için değiştirici Method1 , BaseClass.virtual Önce veya sonra değiştirici eklenebilir public.

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

Projeyi yeniden çalıştırın.Özellikle son iki satırı aşağıdaki çıktıyı dikkat edin.

// Output:
// Base - Method1
// Base - Method2
// Derived - Method1
// Derived - Method2
// Derived - Method1
// Base - Method2

Kullanımını override sağlayan değiştirici bcdc erişim için Method1 içinde tanımlanan yöntemi DerivedClass.Devralma hiyerarşisi içinde istenen davranışı genellikle olur.Türetilmiş sınıftan türetilmiş bir sınıf tanımlanan yöntemleri kullanmak üzere oluşturulan değerlere sahip nesneleri istediğiniz.Bu davranışı kullanarak elde override temel sınıf yöntemi genişletmek için.

Aşağıdaki kod, tam bir örnek 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.Bu örnek üç sınıfı tanımlar: adında bir temel sınıf Car ve buradan, türetilmiş iki sınıf ConvertibleCar ve Minivan.Temel sınıf içeren bir DescribeCar yöntemi.Yöntem temel bir araba açıklamasını görüntüler ve sonra çağırır ShowDetails ek bilgi sağlamak için.Her üç sınıfları tanımlayan bir ShowDetails yöntemi.new Değiştirici tanımlamak için kullanılan ShowDetails , ConvertibleCar sınıfı.override Değiştirici tanımlamak için kullanılan ShowDetails , Minivan sınıfı.

// 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.");
    }
}

Örneğin hangi sürümünü test ShowDetails olarak adlandırılır.Aşağıdaki yöntem TestCars1, her sınıfın bir örneğini bildirir ve ardından çağırır DescribeCar her bir örneğinde.

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("----------");
}

TestCars1Aşağıdaki çıktıyı üretir.Sonuçlar için özellikle dikkat edin car2, büyük olasılıkla olduğu beklediğinize değil.Nesne türü ConvertibleCar, ancak DescribeCar sürümüne erişmek değil ShowDetails , tanımlanmış ConvertibleCar bu yöntemi ile bildirildiğinden sınıf new değiştiricisi, değil override değiştirici.Sonuç olarak, bir ConvertibleCar nesneyi görüntüler aynı tanım olarak bir Car nesnesi.Sonuçlar için kontrast car3, olduğu bir Minivan nesnesi.Bu durumda, ShowDetails olarak bildirilmiş bir yöntemi Minivan geçersiz kılar sınıf ShowDetails olarak bildirilmiş bir yöntemi Car sınıf ve görüntülenen açıklamayı 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.
// ----------

TestCars2türündeki nesnelerin listesini oluşturur Car.Alınan değerler nesnelerin örneği Car, ConvertibleCar, ve Minivan sınıfları.DescribeCarListedeki her bir öğesi olarak adlandırılır.Aşağıdaki kod tanımı gösterir 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("----------");
    }
}

Aşağıdaki çıkış görüntülenir.Tarafından görüntülenen çıktı aynı olduğunu fark TestCars1.ShowDetails Yöntemi ConvertibleCar sınıfı değil adlı, nesne türü olmasına bakılmaksızın, ConvertibleCar, olarak TestCars1, veya Car, olarak TestCars2.Öte yandan, car3 çağrıları ShowDetails yönteminden Minivan türü olup her iki durumda da sınıf Minivan veya Car.

// TestCars2
// ----------
// Four wheels and an engine.
// Standard transportation.
// ----------
// Four wheels and an engine.
// Standard transportation.
// ----------
// Four wheels and an engine.
// Carries seven people.
// ----------

Yöntemleri TestCars3 ve TestCars4 örneği.Bu yöntemleri çağırmak ShowDetails , doğrudan ilk nesnelerden bildirilen türü için ConvertibleCar ve Minivan (TestCars3), nesne türü için bildirilen daha sonra Car (TestCars4).Aşağıdaki kod, bu iki yöntem 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 örnek sonuçları karşılık gelen aşağıdaki çıktıyı üretir.

// TestCars3
// ----------
// A roof that opens up.
// Carries seven people.

// TestCars4
// ----------
// Standard transportation.
// Carries seven people.

Aşağıdaki kod, tam proje ve çıktısı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.");
        }
    }

}

Ayrıca bkz.

Başvuru

Sınıflar ve Yapılar (C# Programlama Kılavuzu)

Geçersiz Kılma ve Yeni Anahtar Sözcüklerle Sürüm Oluşturma (C# Programlama Kılavuzu)

base (C# Başvurusu)

abstract (C# Başvurusu)

Kavramlar

C# Programlama Kılavuzu