Скрытие методов и свойств

Последнее обновление: 29.12.2021

В прошлой теме было рассмотрено определение и переопределение виртуальных методов. Другим способом изменить функциональность метода, унаследованного от базового класса, является скрытие (shadowing / hiding).

Фактически скрытие метода/свойства представляет определение в классе-наследнике метода или свойства, которые соответствует по имени и набору параметров методу или свойству базового класса. Для скрытия членов класса применяется ключевое слово new. Например:

class Person
{
	public string Name { get; set; }
	public Person(string name)
    {
        Name = name;
    }
	public void Print()
	{
		Console.WriteLine($"Name: {Name}");
	}
}
class Employee : Person
{
	public string Company { get; set; }
	public Employee(string name, string company)
				: base(name)
	{
		Company = company;
	}
	public new void Print()
	{
		Console.WriteLine($"Name: {Name}   Company: {Company}");
	}
}

Здесь определен класс Person, представляющий человека, и класс Employee, представляющий работника предприятия. Employee наследует от Person все свойства и методы. Но в классе Employee кроме унаследованных свойств есть также и собственное свойство Company, которое хранит название компании. И мы хотели бы в методе Print выводить информацию о компании вместе с именем на консоль. Для этого определяется метод Print с ключевым словом new, который скрывает реализацию данного метода из базового класса.

В каких ситуациях можно использовать скрытие? Например, в примере выше метод Print в базовом классе не является виртуальным, мы не можем его переопределить, но, допустим, нас не устраивает его реализация для производного класса, поэтому мы можем воспользоваться сокрытием, чтобы определить нужный нам функционал.

Используем эти классы в программе в методе Main:

Person bob = new Person("Bob");
bob.Print();	// Name: Bob

Employee tom = new Employee("Tom", "Microsoft");
tom.Print();	// Name: Tom  Company: Microsoft

Консольный вывод программы:

Name: Bob
Name: Tom  Company: Microsoft

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

class Employee : Person
{
	public string Company { get; set; }
	public Employee(string name, string company)
				: base(name)
	{
		Company = company;
	}
	public new void Print()
	{
		base.Print();	// вызываем метод Print из базового класса Person
		Console.WriteLine($"Company: {Company}");
	}
}

Скрытие свойств

Подобным обазом мы можем организовать скрытие свойств:

Person bob = new Person("Bob");
Console.WriteLine(bob.Name);	// Bob

Employee tom = new Employee("Tom", "Microsoft");
Console.WriteLine(tom.Name);    // Mr./Ms. Tom

class Person
{
	public string Name { get; set; }
	public Person(string name)
    {
        Name = name;
    }
}
class Employee : Person
{
	// скрываем свойство Name базового класса
	public new string Name
	{
		get => $"Mr./Ms. {base.Name}";
		set => base.Name = value;

	}
	public string Company { get; set; }
	public Employee(string name, string company)
				: base(name)
	{
		Company = company;
	}
}

В данном случае в классе Employee переопределено свойство Name. В блоке get нем мы берем значение свойства из базовового класса Person и присоединяем к нему "Mr./Ms.". В блоке set передаем полученное значение в реализацию свойства Name базового класса Person

Скрытие переменных и констант

В отличие от переопределения C# позволяет применять скрытие к переменным (как к статическим, так и нестатическим) и константам, также используя ключевое слово new:

Console.WriteLine(Person.minAge);	  // 1
Console.WriteLine(Person.typeName);   // Person

Console.WriteLine(Employee.minAge);		// 18
Console.WriteLine(Employee.typeName);   // Employee

class Person
{
	public readonly static int minAge = 1;
	public const string typeName = "Person";
}
class Employee : Person
{
	// скрываем поля и константы базового класса
	public new readonly static int minAge = 18;
	public new const string typeName = "Employee";
}
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850