Новое сокрытие ключевых слов и методов - программирование

Новое сокрытие ключевых слов и методов

Новое ключевое слово используется для скрытия реализации базового класса. Но я не уверен, почему следующий код выводит результат как Baseclass

class Baseclass
{ 
    public void fun()
    { 
        Console.Write("Base class" + " ");
    } 
} 
class Derived1: Baseclass
{ 
    new void fun()
    {
        Console.Write("Derived1 class" + " "); 
    } 
} 
class Derived2: Derived1
{ 
    new void fun()
    { 
        Console.Write("Derived2 class" + " ");
    }
}
class Program
{ 
    public static void Main(string[ ] args)
    { 
        Derived2 d = new Derived2(); 
        d.fun(); 
    } 
} 

Мы скрываем реализацию fun в производном2, но все же базовый класс называется почему так? Я что-то упускаю?

4b9b3361

Ответ 1

Derived2.fun является закрытым (это модификатор доступа по умолчанию для членов типа). Это не видно за пределами класса. Только видимый fun метод вне класса Baseclass.fun и, следовательно, он вызывается.

Вам нужно, чтобы ваш Derived2.fun был видимым вне класса, чтобы получить ожидаемый результат. Вы можете сделать это, сделав его общедоступным/внутренним.

Ответ 2

Как правило, скрытие в С# работает следующим образом: "hider" (метод или поле или все, что объявлено с ключевым словом new) принимает на себя все "функциональные возможности", которые он может от всего, что "скрыто". Например:

class Baseclass
{ 
    public void fun()
    { 
        Console.Write("Base class" + " ");
    } 
} 
class Derived1 : Baseclass
{ 
    new public void fun()
    {
        Console.Write("Derived1 class" + " "); 
    } 
}

Здесь fun in Derived1 полностью скрывает fun в Baseclass, потому что у них есть точно такая же "функциональность": они оба являются методами и являются public, т.е. доступны из любого места.

Однако, если "hider" не охватывает все функции "скрытого" члена, он все равно будет там, готовый выполнить свою работу. Пример:

class Baseclass
{ 
    public void fun()
    { 
        Console.Write("Base class" + " ");
    } 
} 
class Derived1 : Baseclass
{ 
    new public int fun;
}

Здесь Baseclass.fun - это метод, а Derived1.fun - поле.

Вы можете получить доступ к полю "скрытие" в выражении присваивания следующим образом: int a = new Derived1().fun;. Поскольку он скрывает метод базового класса fun, вы не можете получить к нему доступ (метод) следующим образом: System.Action a = new Derived1().fun; не работает.

Но что произойдет, если мы что-то сделаем с fun, что поле int не может сделать? new Derived1().fun(); будет работать, вызывая fun в базовом классе!

Этот конкретный пример даже упоминается в MSDN на странице новой страницы модификатора:

Как правило, константа, поле, свойство или тип, вводимые в класс или struct, скрывают всех членов базового класса, которые делят свое имя. Есть особые случаи. Например, если вы объявляете новое поле с именем N, чтобы иметь тип, который не является invocable, а базовый тип объявляет N как метод, новое поле не скрывает базовое объявление в синтаксисе вызова.

Ваше дело очень похоже. Методы fun в ваших двух производных классах скрывают только часть исходного fun в базовом классе. Если вы вызываете fun изнутри Derived1 или Derived2, вы получите версию "hider" foo соответствующего класса. Однако, когда вы вызываете foo извне ваших трех классов, вызывается метод public Baseclass, потому что его функция public не была скрыта...