Наследование и сокрытие имен

54

В производном классе можно определить член с таким же именем, как и у члена его базового класса. В этом случае член базового класса скрывается в производном классе. И хотя формально в C# это не считается ошибкой, компилятор все же выдаст сообщение, предупреждающее о том, что имя скрывается. Если член базового класса требуется скрыть намеренно, то перед его именем следует указать ключевое слово new, чтобы избежать появления подобного предупреждающего сообщения. Следует, однако, иметь в виду, что это совершенно отдельное применение ключевого слова new, не похожее на его применение при создании экземпляра объекта:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class MyClass
    {
        public int x = 10, y = 5, z = 6;
    }

    class ClassA : MyClass
    {
        // Скрываем члены класса MyClass
        public new int x = 12, y = -2, z = -5;        
    }

    class ClassB : MyClass
    {
        public int x;
    }

    class Program
    {
        static void Main()
        {
            ClassA obj1 = new ClassA();
            ClassB obj2 = new ClassB();

            Console.WriteLine("Координаты объекта obj1: {0} {1} {2}",obj1.x,obj1.y,obj1.z);
            Console.WriteLine("Координаты объекта obj2: {0} {1} {2}", obj2.x, obj2.y, obj2.z);

            Console.ReadLine();
        }
    }
}
Сокрытие имен C#

Несмотря на то, что данный пример работает корректно, IDE-среда Visual Studio 2010 выводит следующие предупреждающие сообщения в отношении члена класса ClassB x:

Предупреждения при неявном сокрытии имен

Применение ключевого слова base для доступа к скрытому имени

Имеется еще одна форма ключевого слова base, которая действует подобно ключевому слову this, за исключением того, что она всегда ссылается на базовый класс в том производном классе, в котором она используется. Ниже эта форма приведена в общем виде:

base.член

где член может обозначать метод или переменную экземпляра. Эта форма ключевого слова base чаще всего применяется в тех случаях, когда под именами членов производного класса скрываются члены базового класса с теми же самыми именами. С помощью ключевого слова base могут также вызываться скрытые методы. Давайте рассмотрим пример:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class MyClass
    {
        public int x;
    }

    class ClassA : MyClass
    {
        new int x = 10;

        public void someMethod(int i1, int i2)
        {
            // Координата x из базового класса MyClass
            base.x = i1;
            Console.WriteLine("x (в базовом классе) = " + base.x);
            // Координата x из класса ClassA
            x = i2;
            Console.WriteLine("x (в производном классе) = " + x);
        }
    }

    class Program
    {
        static void Main()
        {
            ClassA obj1 = new ClassA();
            obj1.someMethod(1,25);

            Console.ReadLine();
        }
    }
}
Пройди тесты
Лучший чат для C# программистов